首页 文章

如何在ngFor angular 2中使用track

提问于
浏览
43

尝试了我能猜出的每一种语法都无法使其有效!

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

对我有用的唯一方法是

  • 在控制器类中创建方法

识别(索引,帖子:帖子)

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

这是唯一的方法吗?我不能只为trackBy指定内联的属性名称吗?

4 回答

  • 9

    正如您已经认识到的那样,使用函数是在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开始,这也会在应用程序中引发错误 .

  • 77

    正如在@Eric评论中指出的,经过大量的阅读和游戏,这里是如何在angular2中使用trackBy

    • 首先需要知道它与angular1的语法不同,现在需要将它与for循环中的 ; 分开 .

    Usage 1: Track by property of object

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

    • 创建一个局部变量帖子;

    • 你告诉trackBy要等到这个局部变量准备就绪“你这样做是通过使用elvis operator 'the question mark after the variable name',然后使用它的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"
    

    Usage 2: Track using your own Function

    @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};
    });
    
  • -5

    trackBy背后的概念:

    • ngFor of angular通过跟踪对象标识自动优化修改/创建/删除对象的显示 . 因此,如果您在列表中创建所有新对象,然后使用 ngFor ,它将呈现整个列表 .

    • 让我们考虑一个场景,尽管所有 ngFor 优化,渲染仍然需要时间 . 在那种情况下,我们使用 trackBy . 因此,我们可以提供另一个参数来跟踪对象,而不是作为默认跟踪条件的对象标识 .

    一个运行的例子:

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

    这个简单的解决方案适合我的场景

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

    EDIT: 正如Jeremy Thille所建议的那样,你应该使用 let 而不是 # ,因为在最新版本的Angular2中不推荐使用 # .

相关问题