comment utiliser la piste à l'intérieur de ngFor angular 2

a essayé toutes les syntaxes que je peux deviner ne pouvait pas faire ça fonctionne !

<!--- THIS WORKS FINE --->
<ion-card *ngFor="#post of posts">
{{post|json}}
</ion-card>

<!--- BLANK PAGE --->
<ion-card *ngFor="#post of posts track by post.id">
{{post|json}}
</ion-card>

<!--- Exception : Cannot read property 'id' of undefined --->
<ion-card *ngFor="#post of posts;trackBy:post.id">
{{post|json}}
</ion-card>

<!--- Exception : Cannot read property 'undefined' of undefined --->
<ion-card *ngFor="#post of posts;trackBy:posts[index].id">
{{post|json}}
</ion-card>

<!--- Blank page no exception raised !  --->
<ion-card *ngFor="#post of posts;#index index;trackBy:posts[index].id">
{{post|json}}
</ion-card>

la seule méthode qui a fonctionné pour moi a été

  1. méthode de Création de Classe controller

    identifier (index, post: Post){ retour de courrier.id }

et

<ion-card *ngFor="#post of posts;trackBy:identify">
</ion-card>

est-ce le seul moyen ? est-ce que je ne peux pas juste spécifier la ligne de propriété pour trackBy ?

38
demandé sur Mostafa Fateen 2016-03-31 04:57:07

4 réponses

comme indiqué dans le commentaire @Eric, et après beaucoup de lecture et de jeu, voici comment utiliser trackBy en angular2

  1. la première chose que vous devez savoir sa syntaxe pas la même que angular1, maintenant vous devez le séparer de la boucle for avec un ; .

Utilisation 1: Piste d'une propriété de l'objet

 // starting v2. 1 this will throw error, you can only use functions in trackBy from now on

<ion-card *ngFor="let post of posts;trackBy:post?.id">
</ion-card> // **DEPRECATED**
---or---
<ion-card *ngFor="let post of posts;trackBy:trackByFn">
</ion-card>

ici vous demandez angular2 à

  1. créer un poste variable local;
  2. vous dites à trackBy d'attendre jusqu'à ce que cette variable locale soit prête "vous faites cela en utilisant l'opérateur elvis 'le point d'interrogation après le variable name', puis utiliser son id comme tracker.

donc

// starting v2. 1 this will throw error, you can only use functions in trackBy from now on

*ngFor="#post of posts;trackBy:post?.id"

est-ce que même en tant angulaire du 1

ng-repeat="post in posts track by post.id"

Utilisation 2: Piste à l'aide de votre propre Fonction

@Page({
    template: `
        <ul>
            <li *ngFor="#post of posts;trackBy:identify">
              {{post.data}}
            </li>
        </ul>
    `
})
export class HomeworkAddStudentsPage {
    posts:Array<{id:number,data:string}>;   

    constructor() {
        this.posts = [  {id:1,data:'post with id 1'},
                        {id:2,data:'post with id 2'} ];
    }

    identify(index,item){
      //do what ever logic you need to come up with the unique identifier of your item in loop, I will just return the object id.
      return post.id 
     }

}

trackBy peut prendre un nom de callback, et il l'appellera pour nous fournissant 2 paramètres: l'index de la boucle et l'élément courant.

pour obtenir la même chose avec L'Angle 1, je faisais:

<li ng-repeat="post in posts track by identify($index,post)"></li>

app.controller(function($scope){
  $scope.identify = function(index, item) {return item.id};
});
71
répondu Zalaboza 2017-08-14 21:06:24

comme vous l'avez déjà reconnu, l'utilisation d'une fonction est la seule façon d'utiliser trackBy en angle 2

<ion-card *ngFor="#post of posts;trackBy:identify"></ion-card>

la documentation officielle indique que https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html

toutes les autres informations sur <ion-card *ngFor="let post of posts;trackBy:post?.id"></ion-card> sont fausses. En commençant par L'Angular 2.4.1 ceci lancera également une erreur dans l'application.

9
répondu Volker Andres 2016-12-22 12:56:01

Le concept derrière trackBy:

  1. ngFor of angular optimise automatiquement l'affichage des objets modifiés/créés/supprimés en traçant l'identité de l'objet. Ainsi, si vous créez tous les nouveaux objets dans la liste et que vous utilisez ensuite ngFor , cela rendra la liste entière.

  2. considérons un scénario où malgré toutes les optimisations ngFor , le rendu prend encore du temps. Dans dans ce cas, on utilise trackBy . Ainsi, nous pouvons fournir un autre paramètre pour suivre les objets que l'identité de l'objet qui est un critère de suivi par défaut.

l'exécution d'Un exemple:

<!DOCTYPE html>
<html>

<head>
    <title>Angular 2.1.2 + TypeScript Starter Kit</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <script src="https://unpkg.com/zone.js@0.6.21/dist/zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.9/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.41/dist/system.js"></script>
    <script src="https://unpkg.com/typescript@2.1.4/lib/typescript.js"></script>
    <script src="config.js"></script>
  <script>
      System.import('app')
          .catch(console.error.bind(console));
    </script>
</head>

<body>
    <my-app>
        loading...
    </my-app>
</body>

</html>
2
répondu Ruchi Wadhwa 2017-05-19 11:41:05

Cette solution simple a fonctionné pour mon scénario

<ion-card *ngFor="let post of posts;let i = index"> 
    {{i+1}}
</ion-card>

EDIT: Comme suggéré par Jeremy Thille ci-dessous, vous devez utiliser let au lieu de # , # est déconseillée dans les dernières versions de Angular2.

-5
répondu mi-ho 2017-01-04 15:57:50