web-dev-qa-db-fra.com

Angularjs faux $ index après ordrePar

Je suis nouveau sur Angular.js et j'ai quelques problèmes pour trier mon tableau et travailler sur les données triées.

J'ai une liste d'éléments et je veux donc la trier par "Store.storeName", qui fonctionne jusqu'à présent. Mais après avoir trié les données, ma fonction de suppression ne fonctionne plus. Je pense que c'est parce que l'indice $ est incorrect après le tri, et donc les données erronées sont supprimées.

Comment puis-je résoudre ça? Vous commandez les données dans le périmètre et non dans la vue? Comment faire ça?

Voici quelques codes pertinents:

Dans la vue:

<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>

Et dans mon contrôleur, j'ai cette fonction de suppression, qui devrait supprimer les données spécifiques:

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

Cela fonctionne bien avant de commander dans la vue. S'il manque quelque chose d'important, laissez-moi maintenant.

Merci!

90
FuzzBuzz

Au lieu de cela ou relayer sur le $index - qui - comme vous l'avez remarqué - pointe vers l'index d'un tableau trié/filtré, vous pouvez transmettre l'élément lui-même à votre fonction removeItem:

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

et modifiez la fonction removeItem pour rechercher un index à l'aide de la méthode indexOf d'un tableau, comme suit:

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

J'ai commencé à apprendre angular et j'ai été confronté à des problèmes similaires, et sur la base de la réponse de @ pkozlowski-opensource, je l'ai résolu avec quelque chose comme:

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

J'ai eu le même problème et d'autres réponses à ce sujet ne conviennent pas à ma situation.

J'ai résolu mon problème avec le filtre personnalisé:

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

qui peut être utilisé de cette façon:

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

puis en HTML, vous pouvez utiliser item.index au lieu de $index.

Cette méthode convient aux collections d'objets.

Veuillez prendre en compte que ce filtre personnalisé doit être le premier de la liste de tous les filtres appliqués (orderBy, etc.) et qu'il ajoutera la propriété supplémentaire index (le nom est personnalisable) dans chaque objet de la collection.

19
mile

Essaye ça:

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

}

Vous pouvez trouver une explication détaillée dans cette entrée dans mon blog.

4
Dimitry

J'aurais juste laissé un commentaire, mais je n'ai pas la "réputation".

la solution de mile est exactement ce dont j'avais besoin aussi. Pour répondre à la question de pkozlowski.opensource: lorsque vous avez imbriqué ngRepeats, une liste dynamique (par exemple, où vous autorisez les suppressions), ou les deux (ce qui est mon cas), en utilisant $index ne fonctionne pas car ce sera le mauvais index pour les données back-end après le tri et l'utilisation de ngInit pour mettre en cache la valeur ne fonctionne pas non plus, car elle n'est pas réévaluée lorsque la liste est modifiée.

Notez que la solution de mile permet de personnaliser le nom de la propriété d’index attaché en passant un paramètre <tr ng-repeat="item in items | index:'originalPosition' | orderBy:'Store.storeName'">

Ma version modifiée:

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

Au cas où quelqu'un aurait besoin d'utiliser $index, vous pouvez donner un nom au tableau trié/filtré:

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

Voir ma réponse ici .

1
hmk