Angularjs wrong index índice después de OrderBy


Soy nuevo en Angular.js y tienen algunos problemas para ordenar mi matriz y trabajar en los datos ordenados.

Tengo una lista con artículos y quiero ordenarla por " Tienda.StoreName", que está funcionando hasta ahora. Pero después de ordenar los datos, mi función de borrado ya no funciona. Creo que eso es porque el índice $está mal después de ordenar, y por lo que los datos incorrectos se eliminan.

¿Cómo puedo resolver eso? Ordenar los datos en el ámbito y no en la vista? ¿Cómo hacer eso?

Aquí hay algunos código pertinente:

En la vista:

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

Y en mi controlador tengo esta función de eliminación, que debería eliminar los datos específicos:

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

Esto funciona bien antes de ordenar en la vista. Si falta algo importante, por favor déjame ahora.

Gracias!

Author: Fortin, 2013-04-20

6 answers

En su lugar o retransmitiendo en el $index - que - como ya ha notado-apuntará al índice en una matriz ordenada / filtrada, puede pasar el elemento en sí a su función removeItem:

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

Y modifique la función removeItem para encontrar un índice usando el método indexOf de un array de la siguiente manera:

$scope.removeItem = function(item){
   $scope.items.splice($scope.items.indexOf(item),1);
}
 135
Author: pkozlowski.opensource,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-20 09:49:15

Tuve el mismo problema y otras respuestas en este tema no son adecuadas para mi situación.

He resuelto mi problema con el filtro personalizado:

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

Que se puede usar de esta manera:

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

Y luego en HTML puedes usar item.index en lugar de $index.

Este método es adecuado para las colecciones de objetos.

Por favor, tenga en cuenta que este filtro personalizado debe ser el primero en la lista de todos los filtros aplicados (OrderBy, etc.).) y añadirá la propiedad adicional index (el nombre es personalizable) en cada objeto de la colección.

 19
Author: mile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-10 03:33:22

Comencé a aprender angular y enfrenté problemas similares, y basado en la respuesta de @pkozlowski-opensource, lo resolví solo con algo como

<a>
  <img src="img/delete.png" ng-click="removeItem(items.indexOf(item))">
  {{items.indexOf(item)}}
</a> 
 19
Author: ad_nm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-05 13:53:01

Prueba esto:

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

}

Puedes encontrar una explicación detallada en esta entrada en mi blog.

 4
Author: Dimitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-06 13:31:02

Simplemente habría dejado un comentario, pero no tengo la "reputación".

La solución de Mile es exactamente lo que yo también necesitaba. Para responder a pkozlowski.pregunta de opensource: cuando has anidado ngRepeats, una lista dinámica (por ejemplo, donde permites las eliminaciones), o ambas (que es mi caso), usar $index no funciona porque será el índice incorrecto para los datos del back-end después de ordenar y usar ngInit para almacenar en caché el valor tampoco funciona porque no se vuelve a evaluar cuando la lista cambio.

Tenga en cuenta que la solución de mile permite que el nombre de la propiedad de índice adjunto se personalice pasando un parámetro <tr ng-repeat="item in items | index:'originalPosition' | orderBy:'Store.storeName'">

Mi versión modificada:

.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
Author: MarkMYoung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-06 18:45:43

En caso de que alguien necesite usar $index, puede darle un nombre a la matriz ordenada / filtrada :

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

Ver mi respuesta aquí.

 -2
Author: hmk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-24 12:14:21