web-dev-qa-db-ja.com

ngFor angular 2内でトラックを使用する方法

私が推測できるすべての構文を試してみて、それを機能させることはできませんでした!

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

私のために働いた唯一のアプローチは

  1. コントローラークラスでのメソッドの作成

    identity(index、post:Post){return post.id}

そして

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

これは唯一の方法ですか? trackByにインラインでプロパティ名を指定することはできませんか?

44
Zalaboza

@Ericコメントで指摘されているように、そして多くの読書と遊びの後に、angular2でtrackByを使用する方法を以下に示します。

  1. まず、angular1とは異なる構文を知っておく必要があるのは、;を使用してforループから分離する必要があることです。

使用法1:オブジェクトのプロパティで追跡

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

ここでは、angular2に尋ねます

  1. ローカル変数ポストを作成します。
  2. このローカル変数の準備ができるまで待機するようにtrackByに指示します。「elvis演算子「変数名の後の疑問符」を使用してそれを行い、そのIDをトラッカーとして使用します。

そう

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

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

角度の1と同じものです

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

使用法2:独自の関数を使用して追跡する

@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はコールバックの名前を取ることができ、ループのインデックスと現在のアイテムの2つのパラメーターを指定して呼び出します。

Angular 1で同じことを達成するために、私は次のことをしました。

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

app.controller(function($scope){
  $scope.identify = function(index, item) {return item.id};
});
82
Zalaboza

すでに認識したように、Angular 2でtrackByを使用する唯一の方法は関数を使用することです

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

公式ドキュメントには、 https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html

<ion-card *ngFor="let post of posts;trackBy:post?.id"></ion-card>に関するその他の情報はすべて間違っています。 Angular 2.4.1以降では、アプリケーションでエラーもスローされます。

9
Volker Andres

TrackByの背後にある概念:

  1. ngFor of angularは、オブジェクトIDを追跡することにより、変更/作成/削除されたオブジェクトの表示を自動的に最適化します。そのため、リストにすべての新しいオブジェクトを作成してからngForを使用すると、リスト全体がレンダリングされます。

  2. すべてのngFor最適化にもかかわらず、レンダリングにまだ時間がかかるシナリオを考えてみましょう。その場合、trackByを使用します。そのため、デフォルトの追跡基準であるオブジェクトID以外のオブジェクトを追跡する別のパラメーターを提供できます。

実行例:

<!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/[email protected]/dist/zone.js"></script>
    <script src="https://unpkg.com/[email protected]/Reflect.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/system.js"></script>
    <script src="https://unpkg.com/[email protected]/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
Ruchi Wadhwa