AngularJS: ng-repeat avec liste dynamique, sans reconstruire l'arborescence DOM entière?


azote:

J'utilise ng-repeat sur une ligne de table avec des données d'un tableau JSON récupérées à partir d'un serveur. Mon objectif est que la liste soit mise à jour automatiquement chaque fois qu'un élément est ajouté, supprimé ou modifié sur le serveur, sans affecter les éléments non modifiés. Dans l'implémentation finale, ces lignes de table contiendront également des liaisons bidirectionnelles <input>et des <select>éléments pour renvoyer les mises à jour au serveur. Certaines des options disponibles dans les <select>éléments seront également générées à l'aide des directives ng-repeat d'une autre liste qui peut également changer.

Jusqu'à présent, chaque fois qu'un nouveau tableau provient du serveur (actuellement interrogé toutes les deux secondes), toute la liste ng-repeat est supprimée et régénérée. Ceci est problématique car cela interfère avec la sélection de texte, détruit les champs de saisie même s'ils sont actuellement modifiés par l'utilisateur et s'exécute probablement beaucoup plus lentement que nécessaire.

J'ai écrit d'autres applications Web qui font ce que je veux en utilisant jQuery et la manipulation DOM, mais le code finit par être vraiment poilu et le développement prend du temps. J'espère utiliser AngularJS et la liaison de données pour accomplir cela en une fraction du code et du temps.

Alors, voici la question: est-il possible de mettre à jour le tableau de sauvegarde de cette façon, mais de modifier uniquement les éléments DOM correspondant aux éléments / propriétés qui ont réellement changé?


Voici un cas de test minimal qui simule une interrogation périodique en utilisant un tableau codé en dur dans une minuterie (voir en direct sur http://jsfiddle.net/DWrmP/ ). Notez que la sélection de texte est effacée toutes les 500 ms en raison des éléments supprimés et recréés.

HTML

<body ng-app="myApp">
    <table ng-controller="MyController">
        <tr ng-repeat="item in items | orderBy:'id'">
            <td>{{item.id}}</td>
            <td>{{item.data}}</td>
        </tr>
    </table>
</body>

JavaScript

angular.module('myApp', []).controller(
    'MyController', [
        '$scope', '$timeout',
        function($scope, $timeout) {
            $scope.items = [
                { id: 0, data: 'Zero' }
            ];

            function setData() {
                $scope.items = [
                    { id: 1, data: 'One' },
                    { id: 2, data: 'Two' },
                    { id: 5, data: 'Five' },
                    { id: 4, data: 'Four' },
                    { id: 3, data: 'Three' }
                    ];
                $timeout(setData, 500);
            }
            $timeout(setData, 500);
        }
        ]
);
dasho:

Pour ceux qui trouvent cela sur Google, la page ci-dessous décrit une fonctionnalité d'AngularJS 1.2 qui aide à résoudre ce problème:

http://www.bennadel.com/blog/2556-Using-Track-By-With-ngRepeat-In-AngularJS-1-2.htm


Modifier pour ajouter: les phrases les plus importantes de l'article lié, au cas où le lien mourrait:

Avec la nouvelle syntaxe «track by», je peux maintenant indiquer à AngularJS quelle propriété d'objet (ou chemin de propriété) doit être utilisée pour associer un objet JavaScript à un nœud DOM. Cela signifie que je peux échanger des objets JavaScript sans détruire les nœuds DOM tant que l'association "track by" fonctionne toujours.

Articles connexes


angularjs et barre de boutons dynamique avec ng-repeat

Marc J'utilise angularjset je souhaite définir dynamiquement une barre de boutons. Quelque chose comme ça: <div class="bar bar-subheader" ng-show="tournament.gameTableCreated"> <div class="button-bar"> <div ng-repeat="category in categories | order

angularjs ng-repeat avec json / object dynamique

Jaison james Je recherche une solution pour la structure de données dynamique (incohérente comme un nom de propriété différent et une longueur de propriété) avec ng-repeat. un exemple de code est ci-dessous. $scope.data = [{ "table":[{ "emp

AngularJS ng-repeat sans élément html

nehz: J'utilise actuellement ce morceau de code pour afficher une liste: <ul ng-cloak> <div ng-repeat="n in list"> <li><a href="{{ n[1] }}">{{ n[0] }}</a></li> <li class="divider"></i> </div> <li>Additional item</li> </ul> Cependa

Liste déroulante AngularJS Data Driven avec ng-repeat

mtkilic J'ai essayé de créer un menu déroulant en cascade basé sur les données avec Angularjs pour mon graphique. Voici ce que j'ai jusqu'à présent PLUNKER Year: <select id="YearSelector"> <option ng-repeat="year in filterOptions.stores">{{year.year}}</opti

Liste déroulante AngularJS avec arborescence

Azad Shaikh Je suis nouveau sur angularjs, je souhaite utiliser une liste déroulante avec une structure arborescente. J'ai utilisé la liste déroulante et le contrôle de l'arborescence séparément, mais j'ai du mal à les utiliser ensemble. Quelqu'un peut-il avoi