如何使用angular 2的内部跟踪
尝试了我能猜到的每一种语法都不能让它工作如何使用angular 2的内部跟踪,angular,ngfor,angularjs-track-by,Angular,Ngfor,Angularjs Track By,尝试了我能猜到的每一种语法都不能让它工作 <!--- 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> <
<!--- 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>
{{post | json}}
{{post | json}}
{{post | json}}
{{post | json}}
{{post | json}}
唯一对我有效的方法是
这是唯一的办法吗?我能不能不为trackBy内联指定一个属性名?正如@Eric comment中指出的那样,经过大量阅读和练习,下面是如何在angular2中使用trackBy
将它与for循环分开代码>
// 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>
和angular的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
}
}
@Page({
模板:`
-
{{post.data}
`
})
导出类HomeworkAddStudentsPage{
职位:阵列;
构造函数(){
this.posts=[{id:1,数据:'post with id 1'},
{id:2,数据:'post with id 2'}];
}
识别(索引、项目){
//不管您需要做什么,只要在循环中找到项目的唯一标识符,我就返回对象id。
返回邮政编码
}
}
trackBy可以使用callback的名称,它将为我们调用它,并提供两个参数:循环的索引和当前项
为了实现与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};
});
应用程序控制器(功能($scope){
$scope.identify=函数(索引,项){return item.id};
});
正如您已经认识到的,使用函数是在Angular 2中使用trackBy的唯一方法
<ion-card *ngFor="#post of posts;trackBy:identify"></ion-card>
官方文件指出
关于
的所有其他信息都是错误的。从Angular 2.4.1开始,这也会在应用程序中引发错误。trackBy背后的概念:
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>
Angular 2.1.2+TypeScript初学者工具包
System.import('app')
.catch(console.error.bind(console));
加载。。。
除了其他人的答案之外,我只想添加几个示例(Angular 2+),以明确trackBy的使用
从文件:
为了避免这种昂贵的操作,您可以自定义默认值
跟踪算法。通过向NgForOf提供trackBy选项。
trackBy接受一个有两个参数的函数:index和item。如果
trackBy给定时,角度轨迹会根据
功能
请在此处阅读更多信息:
举个例子可以更好地解释这一点
应用程序组件.ts
array = [
{ "id": 1, "name": "bill" },
{ "id": 2, "name": "bob" },
{ "id": 3, "name": "billy" }
]
foo() {
this.array = [
{ "id": 1, "name": "foo" },
{ "id": 2, "name": "bob" },
{ "id": 3, "name": "billy" }
]
}
identify(index, item) {
return item.id;
}
让我们使用*ngFor
将数组显示为3个div
app.component.html
无trackBy的*ngFor
示例:
<div *ngFor="let e of array;">
{{e.id}} - {{e.name}}
</div>
<button (click)="foo()">foo</button>
<div *ngFor="let e of array; trackBy: identify">
{{e.id}} - {{e.name}}
</div>
<button (click)="foo()">foo</button>
如果我们点击foo
按钮会发生什么
→ 只有第一个div将被刷新。请自己尝试,打开控制台进行验证
如果我们更新了第一个对象而不是整个对象呢
→ 此处无需使用trackBy
它在使用订阅时特别有用,订阅通常看起来像我用数组设计的。所以看起来是这样的:
array = [];
subscription: Subscription;
ngOnInit(): void {
this.subscription = this.fooService.getArray().subscribe(data => {
this.array = data;
});
}
identify(index, item) {
return item.id;
}
你能告诉我trackBy在ngFor中的用途吗?Eric的答案似乎很好。@micronyks它允许您将一个函数传递给*ngFor
,该函数将ngFor
转发给https://angular.io/docs/ts/latest/api/core/IterableDifferFactory-interface.html
(但我还不知道这种差异是如何工作的)https://angular.io/docs/ts/latest/api/core/IterableDifferFactory-interface.html代码> 没有找到。还有其他链接吗?我仍然不清楚trackBy的干净用法。如果这里有人在*ngFor
中发布trackBy用法的示例,我会非常有帮助。我认为“trackBy:post?.id”不起作用。在我的例子中,子元素的状态丢失。一个单独的trackBy函数可以工作(但绝对不方便)。顺便说一句,elvis操作符本身表明出了问题。如果它能工作,那么您就不必在这里使用它(除非集合项可以为null)。我确认,trackBy只与函数一起工作,它与“post?.id”没有错误,但在这种情况下它将与trackBy“null”匹配(您可以检查html并看到),这意味着它根本不跟踪,除了@Olivier comment外,你能不能更新你的帖子以避免对新用户产生误导?你只是看不到一个错误@Zalaboza。从Angular 2.4.1开始,使用*ngFor=“#post of posts;trackBy:post?.id”将抛出一个错误,因为trackBy只接受函数right@Zalaboza,只允许函数,请更新您的帖子。此处讨论:@Zalaboza请您更新您的答案,其中trackBy:post?.id
已被确认无效。不确定为什么您有一个既不运行也没有trackBy示例的“运行示例”,但出于trackBy背后的原因,+1。这只是为了提高性能。@Rap看起来很多
<div *ngFor="let e of array; trackBy: identify">
{{e.id}} - {{e.name}}
</div>
<button (click)="foo()">foo</button>
foo() {
this.array[0].name = "foo";
}
array = [];
subscription: Subscription;
ngOnInit(): void {
this.subscription = this.fooService.getArray().subscribe(data => {
this.array = data;
});
}
identify(index, item) {
return item.id;
}