Angularjs wrong $index after orderBy

冷暖自知 提交于 2019-11-27 03:05:38

Instead or relaying on the $index - which - as you have noticed - will point to the index in a sorted / filtered array, you can pass the item itself to your removeItem function:

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

and modify the removeItem function to find an index using the indexOf method of an array as follows:

$scope.removeItem = function(item){
   $scope.items.splice($scope.items.indexOf(item),1);
}
ad_nm

I started to learn angular and faced similar trouble, and based on the answer of @pkozlowski-opensource, I solved it just with something like

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

I had the same problem and other answers in this topic are not suitable for my situation.

I've solved my problem with custom filter:

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;
    };
});

which can be used this way:

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

and then in HTML you can use item.index instead of $index.

This method is suitable for the collections of objects.

Please, take into account that this custom filter should be the first one in the list of all filters applied (orderBy etc.) and it will add the additional property index (the name is customizable) into the each object of the collection.

Try this:

$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);

}

You can find verbose explanation in this entry in my blog.

I would've just left a comment, but I don't have the "reputation".

mile's solution is exactly what I needed too. To answer pkozlowski.opensource's question: when you have either nested ngRepeats, a dynamic list (e.g. where you allow removals), or both (which is my case), using $index does not work because it will be the wrong index for the back-end data after sorting and using ngInit to cache the value does not work either because it's not re-evaluated when the list changes.

Note that mile's solution allows for the attached index property name to be customized by passing a parameter <tr ng-repeat="item in items | index:'originalPosition' | orderBy:'Store.storeName'">

My tweaked version:

.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 );
    });
})

In case someone needs to use $index, you can give a name to the sorted / filtered array :

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

See my answer here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!