Angularjs在orderBy之后错误$ index

时间:2013-04-20 09:32:56

标签: angularjs sorting indexing angularjs-orderby

我是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}} €</td>                
                <td>{{item.Quantity*item.Price|| 0 | number:2}} €</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);
    }

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

谢谢!

6 个答案:

答案 0 :(得分:139)

代替或转发$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);
}

答案 1 :(得分:20)

我开始学习角度并遇到类似的麻烦,并根据@ pkozlowski-opensource的答案,我解决了它只是像

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

答案 2 :(得分: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(名称可自定义)添加到每个过滤器中集合的对象。

答案 3 :(得分: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);

}

您可以在我的博客中找到this entry中的详细说明。

答案 4 :(得分:1)

我会留下评论,但我没有#34;声誉&#34;。

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

请注意,英里的解决方案允许通过传递参数<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 );
    });
})

答案 5 :(得分:1)

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

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

请参阅我的回答here