92

我是 Angular.js 的新手,在排序数组和处理排序数据时遇到了一些问题。

我有一个包含项目的列表,并希望按“Store.storeName”对它进行排序,到目前为止它正在工作。但是在对数据进行排序后,我的删除功能不再起作用。我认为那是因为 $index 在排序后是错误的,所以错误的数据被删除了。

我该如何解决?在范围内而不是在视图中排序数据?怎么做?

以下是一些相关代码:

在视图中:

<tr ng-repeat="item in items | orderBy:'Store.storeName'">
                <td><input class="toggle" type="checkbox" ng-model="item.Completed"></td>
                <td>{{item.Name}}</td>
                <td>{{item.Quantity}} Stk.</td>
                <td>{{item.Price || 0 | number:2}} €&lt;/td>                
                <td>{{item.Quantity*item.Price|| 0 | number:2}} €&lt;/td>
                <td>{{item.Store.storeName}}</td> 
                <td><a><img src="img/delete.png" ng-click="removeItem($index)">{{$index}}</a></td>
            </tr>

在我的控制器中,我有这个删除功能,它应该删除特定的数据:

$scope.removeItem = function(index){
        $scope.items.splice(index,1);
    }

这在视图中订购之前效果很好。如果缺少重要的东西,请让我现在。

谢谢!

4

6 回答 6

140

相反,或者中继$index- 正如您所注意到的 - 将指向已排序/过滤数组中的索引,您可以将项目本身传递给您的removeItem函数:

<a><img src="img/delete.png" ng-click="removeItem(item)">{{$index}}</a>

并修改removeItem函数以使用数组的方法查找索引indexOf,如下所示:

$scope.removeItem = function(item){
   $scope.items.splice($scope.items.indexOf(item),1);
}
于 2013-04-20T09:49:15.137 回答
23

我开始学习角度并面临类似的问题,根据@pkozlowski-opensource 的回答,我解决了它

<a>
  <img src="img/delete.png" ng-click="removeItem(items.indexOf(item))">
  {{items.indexOf(item)}}
</a> 
于 2014-09-16T05:59:03.423 回答
19

我有同样的问题,这个主题的其他答案不适合我的情况。

我用自定义过滤器解决了我的问题:

angular.module('utils', []).filter('index', function () {
    return function (array, index) {
        if (!index)
            index = 'index';
        for (var i = 0; i < array.length; ++i) {
            array[i][index] = i;
        }
        return array;
    };
});

可以这样使用:

<tr ng-repeat="item in items | index | orderBy:'Store.storeName'">

然后在 HTML 中你可以使用item.index而不是$index.

此方法适用于对象的集合。

请注意,此自定义过滤器应该是应用的所有过滤器列表中的第一个过滤器(orderBy 等),它会将附加属性index(名称可自定义)添加到集合的每个对象中。

于 2014-04-10T03:33:22.073 回答
4

尝试这个:

$scope.remove = function(subtask) {

    var idx = $scope.subtasks.indexOf(subtask),
        st = $scope.currentTask.subtasks[idx];

    // remove from DB
    SubTask.remove({'subtaskId': subtask.id});

    // remove from local array
    $scope.subtasks.splice(idx,1);

}

你可以在我的博客的这篇文章中找到详细的解释。

于 2013-07-25T12:49:39.993 回答
2

如果有人需要使用$index,您可以为排序/过滤的数组命名:

<tr ng-repeat="item in sortedItems = (items | orderBy:'Store.storeName') track by $index">

在这里查看我的答案。

于 2017-07-24T10:40:55.620 回答
1

我本来只是发表评论,但我没有“声誉”。

mile 的解决方案也正是我所需要的。回答 pkozlowski.opensource 的问题:当您有嵌套ngRepeat的 s、动态列表(例如,您允许删除的地方)或两者(这是我的情况)时,使用$index不起作用,因为它将是后端的错误索引排序后的数据和ngInit用于缓存值的数据也不起作用,因为列表更改时不会重新评估它。

请注意,mile 的解决方案允许通过传递参数来自定义附加的索引属性名称<tr ng-repeat="item in items | index:'originalPosition' | orderBy:'Store.storeName'">

我的调整版本:

.filter( 'repeatIndex', function repeatIndex()
{
// This filter must be called AFTER 'filter'ing 
//  and BEFORE 'orderBy' to be useful.
    return( function( array, index_name )
    {
        index_name = index_name || 'index';
        array.forEach( function( each, i )
        {each[ index_name ] = i;});
        return( array );
    });
})
于 2014-08-06T18:45:43.057 回答