如何使用ng-click从数组中删除项目或对象?

Jes*_*zie 259 html edit angularjs

我正在尝试编写一个函数,使我能够在单击按钮时删除项目,但我认为我对该函数感到困惑 - 我使用了$digest吗?

HTML和app.js:

<ul ng-repeat="bday in bdays">
  <li>
    <span ng-hide="editing" ng-click="editing = true">{{bday.name}} | {{bday.date}}</span>
    <form ng-show="editing" ng-submit="editing = false">
      <label>Name:</label>
      <input type="text" ng-model="bday.name" placeholder="Name" ng-required/>
      <label>Date:</label>
      <input type="date" ng-model="bday.date" placeholder="Date" ng-required/>
      <br/>
      <button class="btn" type="submit">Save</button>
      <a class="btn" ng-click="remove()">Delete</a>
    </form>
  </li>
</ul>

$scope.remove = function(){
  $scope.newBirthday = $scope.$digest();
};
Run Code Online (Sandbox Code Playgroud)

cha*_*tfl 540

要删除项目,您需要将其从数组中删除,并可以将bday项目传递给标记中的删除功能.然后在控制器中查找item的索引并从数组中删除

<a class="btn" ng-click="remove(item)">Delete</a>
Run Code Online (Sandbox Code Playgroud)

然后在控制器中:

$scope.remove = function(item) { 
  var index = $scope.bdays.indexOf(item);
  $scope.bdays.splice(index, 1);     
}
Run Code Online (Sandbox Code Playgroud)

Angular会自动检测对bdays数组的更改并进行更新ng-repeat

演示:http://plnkr.co/edit/ZdShIA?p = preview

编辑:如果使用服务器进行实时更新将使用您创建的服务来 $resource同时管理阵列更新它更新服务器

  • 如果您的列表在模板上过滤,直接使用`$ index`会产生错误.这是一个模板的事情; 使用`ng-click ='remove(bday)'然后`arr.splice(arr.indexOf(bday),1)更安全;` (62认同)
  • 如果找不到,则.indexOf(item)`将返回-1,如果不检查它,可能会导致删除数组末尾的项. (11认同)
  • 您不需要传递$ index,因为您可以在方法中使用'this'.$ scope.remove = function(){$ scope.bdays.splice(this.$ index,1); } (6认同)

nXq*_*Xqd 52

这是一个正确的答案:

<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove=function($index){ 
  $scope.bdays.splice($index,1);     
}
Run Code Online (Sandbox Code Playgroud)

在@ charlietfl的回答中.我认为这是错误的,因为你传递$index了参数,但你在控制器中使用了愿望.如我错了请纠正我 :)

  • 如果你的ng-repeat中有orderBy或过滤器,这将不起作用 (17认同)

aze*_*ati 24

如果你在ng-repeat里面

你可以使用一个班轮选项

    <div ng-repeat="key in keywords"> 
        <button ng-click="keywords.splice($index, 1)">

            {{key.name}}
        </button>
    </div>
Run Code Online (Sandbox Code Playgroud)

$index 由angular用于显示数组内部的当前索引 ng-repeat


XML*_*XML 23

$index在基本情况下使用效果非常好,@ charlietfl的答案很棒.但有时,$index还不够.

想象一下,你有一个单独的数组,你在两个不同的ng-repeat中呈现.其中一个ng-repeat是针对具有truthy属性的对象进行过滤,另一个针对falsy属性进行过滤.呈现两个不同的滤波阵列,其源自单个原始阵列.(或者,如果它有助于可视化:也许你有一个单独的人群,你想要为该阵列中的女性进行一次ng-repeat,另一次为同一阵列中的男性.)你的目标:从中可靠地删除原始数组,使用来自已过滤数组成员的信息.

在每个过滤的数组中,$ index将不是原始数组中项目的索引.它将是过滤子阵列中的索引.所以,你不能告诉人指数原来的people数组,你只知道从该指数$ womenmen子阵列.尝试使用它删除,除了你想要的地方,你将有物品从任何地方消失.该怎么办?

如果你很幸运,使用数据模型包含每个对象的唯一标识符,然后使用它而不是$ index,splice从主数组中找到对象和它.(使用下面的示例,但使用该唯一标识符.)但是,如果你没那么幸运?

Angular实际上增加了一个ng重复数组(在主要的原始数组中)中的每个项目,并使用一个名为的唯一属性$$hashKey.您可以搜索原始数组以查找$$hashKey要删除的项目的匹配项,并以此方式删除它.

请注意,这$$hashKey是一个实现细节,未包含在已发布的ng-repeat API中.他们可以随时取消对该物业的支持.但可能不是.:-)

$scope.deleteFilteredItem = function(hashKey, sourceArray){
  angular.forEach(sourceArray, function(obj, index){
    // sourceArray is a reference to the original array passed to ng-repeat, 
    // rather than the filtered version. 
    // 1. compare the target object's hashKey to the current member of the iterable:
    if (obj.$$hashKey === hashKey) {
      // remove the matching item from the array
      sourceArray.splice(index, 1);
      // and exit the loop right away
      return;
    };
  });
}
Run Code Online (Sandbox Code Playgroud)

调用:

ng-click="deleteFilteredItem(item.$$hashKey, refToSourceArray)"
Run Code Online (Sandbox Code Playgroud)

编辑:使用这样的函数,$$hashKey而不是特定于模型的属性名称上的键,还具有使这个函数可以在不同的模型和上下文中重用的显着附加优势.提供您的数组引用和项目引用,它应该可以正常工作.


小智 10

我经常写这样的风格:

<a class="btn" ng-click="remove($index)">Delete</a>


$scope.remove = function(index){
  $scope.[yourArray].splice(index, 1)
};
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助你必须在$ scope和[yourArray]之间使用一个点(.)


Joa*_*uez 9

在接受的答案的基础上,这将有效ngRepeat,filter并更好地处理预期:

控制器:

vm.remove = function(item, array) {
  var index = array.indexOf(item);
  if(index>=0)
    array.splice(index, 1);
}
Run Code Online (Sandbox Code Playgroud)

视图:

ng-click="vm.remove(item,$scope.bdays)"
Run Code Online (Sandbox Code Playgroud)