尝试了我能猜出的每一种语法都无法使其有效!
<!--- 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>
Run Code Online (Sandbox Code Playgroud)
对我有用的唯一方法是
在控制器类中创建方法
识别(索引,帖子:帖子){return post.id}
和
<ion-card *ngFor="#post of …Run Code Online (Sandbox Code Playgroud) 我真的不明白我应该从什么地方回来trackBy.根据我在网上看到的例子,我应该返回对象上某些属性的值.这是对的吗?为什么我将索引作为参数?
例如,在以下情况中:
constructor() {
window.setInterval(() => this.users = [
{name: 'user1', score: Math.random()},
{name: 'user2', score: Math.random()}],
1000);
}
userByName(index, user) {
return user.name;
}
...
<div *ngFor="let user of users; trackBy:userByName">{{user.name}} -> {{user.score}}</div>
Run Code Online (Sandbox Code Playgroud)
尽管名称未更改,但模板中显示的对象仍会更新.为什么?
我有角度ng-repeat指令的问题.目前我在一些项目上工作,从API我得到一个项目列表(有时可能是1k项目),这个列表应该每5秒刷新一次(它是监视相关项目).
当列表长度稍微大一点时,网站重新渲染DOM可能会"慢".结果是角度再生整个DOM(但95%的项目是相同的!)
其中一种可能的方法是将"track by"表达式设置为item.id. 但是这里出现了另一个问题,我还想要重新生成项目,例如其他用户更改了描述.由于track by表达于item.id,因此item.description中的更改未更新DOM中的项目.
有办法跟踪多个属性?也许有些功能?或者也许用"手"做比较?
任何想法,代码样本我会很感激:)
UPDATE
我发现当我设置跟踪到item.id angular时没有为项目重新创建html,只更新已经创建的元素中的值,它似乎"更快"然后删除和创建.以前我虽然有点不同.
固定
对于那些希望通过item.id在ng-repeat USE 轨道上超过> 1k项目获得更好性能的人来说,它将提升你的表现;)
我真的不明白它的track by作用和作用.
我的主要目标是使用它ng-repeat来增加一些精度.
我有这个角度选择:
<select ng-model='obj.status' ng-options='status.code as (status.code + " " + status.phrase) for status in status_codes.data track by status.code'>`
Run Code Online (Sandbox Code Playgroud)
我$scope.status_codes是这样的:
data: [
{
"code":"100",
"phrase":"...",
"spec_title":"RFC7231#6.2",
"spec_href":"http://tools.ietf.org/html/rfc7231#section-6.2"
}
...
]
Run Code Online (Sandbox Code Playgroud)
$scope.obj.status当我更改我的选择时,我的更新为"300"或"100"或其他任何内容,但选择的显示始终为空白.因此,模型更新为选择输入的选定值,但输入未显示当前选定的值,它显示空白项.
如果我改变ng-options是ng-options='status as (status.code ...'有效的,但我只想在我的模型中使用status.code,而不是整个状态数组.是什么赋予了?
我{{obj | json }}在我的HTML和记载:
obj = {
"name": "",
"description": "",
"payload": "",
"status": "200",
"responseHeaders": {
"entry": [
{
"key": "",
"value": ""
},
{
"key": "",
"value": ""
}
]
}
}
Run Code Online (Sandbox Code Playgroud) javascript angularjs angularjs-ng-options angularjs-track-by
我正在将Angular 1.6代码转换为Angular 4,我遇到了一个元素列表问题.Angular 1.6中的代码是:
<select ng-model="$ctrl.level" ng-options="item as item.label for item in $ctrl.referentiel.levels | orderBy : 'index' track by item.id" id="childLevel" name="childLevel" class="size-xl" >
<option value="">Select</option>
</select>
Run Code Online (Sandbox Code Playgroud)
我的列表中未引用对象级别,因为使用对象referentiel.levels加载此列表.但是由于trackby,我的列表元素和我的对象级别之间的匹配完成.因此,当加载我的对象级别时,将在列表中选择该元素.
现在,我尝试使用Reactive Forms转换此代码.在我的HTML代码中,我有:
<select formControlName="levelControl" id="levelSelect" name="levelSelect" class="size-xl">
<option [ngValue]="null">Select</option>
<option *ngFor="let level of referentiel.levels;trackBy:identify" [ngValue]="level">{{level.label }}</option>
</select>
Run Code Online (Sandbox Code Playgroud)
在我的组件中,我有OnInit方法:
(<FormControl>this.myForm.controls.levelControl).setValue(this.level);
Run Code Online (Sandbox Code Playgroud)
方法识别很简单:
identify(index,item){
return item.id;
}
Run Code Online (Sandbox Code Playgroud)
但是这种竞争是不同的.当我使用对象Level设置我的控件的值时,未选择列表中具有相同id的项.
我找到了解决方案,但我不明白为什么它不起作用.我的解决方法是用HTML编写此代码:
<option *ngFor="let level of referentiel.levels;trackBy:identify" [ngValue]="level.id">{{level.label }}</option>
Run Code Online (Sandbox Code Playgroud)
在我的打字稿文件中:
(<FormControl>this.myForm.controls.levelControl).setValue(this.level.id);
Run Code Online (Sandbox Code Playgroud)
所以,现在它正在工作:我的项目在列表中被选中.
在这种情况下,我不明白两个版本的Angular之间的区别.也许我错过了什么......
谢谢你的帮助.
trackBy函数(例如,在ngFor中)提供两个参数:index和item(从正在迭代的集合中)。有没有办法将附加信息(作为参数?)传递给trackBy函数?
我的情况是,我可能会为组件的每个实例(包含ngFor)遍历各种类型,并使用不同的标识字段名称。理想情况下,我希望能够传递第三个参数,该参数指示应读取项目中的哪个字段。
我的组件有点像
\n\n<div class="users-list" *ngIf="datasetPermission !== undefined">\n <div *ngFor="let userpermission of datasetPermission; trackBy : trackByFn">\n <span *ngFor="let user of userpermission.users">\n <span *ngIf="user">\n <span class="shared-user"><span>{{user.emailId}}</span><span ><span class="close icon-key" style=" padding: 0;" (click)="viewPermission($event,userpermission.permissionType,user)"></span><span class="close" style=" padding: 0;" (click)="removeUser(user)">\xc3\x97</span></span></span>\n </span>\n </span>\n </div>\n </div>\nRun Code Online (Sandbox Code Playgroud)\n\ntrackBy 函数为
\n\n public trackByFn(index, userpermission) {\n console.log(userpermission.permissionType);\n return userpermission.permissionType;\n }\nRun Code Online (Sandbox Code Playgroud)\n\n在权限内部,我有一组分配给此权限的用户。我可以从 x <> y 权限集中更新用户。\n当我更新 datasetPermission 数组或向其中添加新元素时,它会更新以下顺序:正在更新/添加数据集。
\n\n我已经浏览了各种帖子,但尚未找到有用的内容。\n我在这里做错了什么吗?任何帮助,将不胜感激。
\n从最近开始,当您没有在每个* ngFor上实现trackBy函数时,Angular styleguide-lint-extender“ Codelyzer”就会发出警告。我想知道为什么这完全是个问题。
trackByFn(index, item) { return index;} // or item.id。如果我从索引切换到item.id,这如何使我的应用程序更快?对于数组插入或删除,索引是最重要的事情。为什么[ngFor]指令应该比较对象标识值呢?_trackByFn。因此,我假设return index-trackBy仍然是默认配置?那么,为什么明确实施它被认为是一个好习惯呢?现在个人而言,我的应用程序中确实有一个大集合(数组),它位于redux存储中。只能用空数组替换它,也可以添加新项目,例如:
return {...state, myArray: [...state.myArray, ...newItems]}),
但从未移动或删除。我item.id代替它跟踪是否有意义index?我真的应该return index;在每个带有* ngFor的组件中实现-function吗?
我在排序和具有 trackBy 函数的数组时遇到问题。用例如下:
我有一个项目数组。所有这些项目都有一个 z-index 属性。我还有一个图层管理器,可以编辑每个项目的 z-index。当我想保存我的项目时,我想根据每个项目的 z-index 属性对我的数组进行排序。我的 ngFor 上还有一个 trackBy,用于限制 *ngFor 上的更改检测量。
使用 *ngFor 上的 trackBy 函数,当我对数组进行排序时,项目会切换位置(这很糟糕)。如果我删除 trackBy 函数,则不会发生这种情况,并且项目将根据 z-index 进行排序。
*ngFor:
<div class="item" *ngFor="let item of items; let i = index;trackBy:getUniqueIdentifier">
Run Code Online (Sandbox Code Playgroud)
trackBy 函数:
getUniqueIdentifier(index, item) {
return this.items.length + ', ' + this.languages._previewLanguage;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,当项目的长度发生变化或我切换语言设置时,*ngFor 会发生变化。我试过添加,+ ', ' + item.zIndex但这不起作用。
排序功能:
sortItemsArrayByZIndex() {
this.items.sort((i1, i2) => {
return (i1.zIndex - i2.zIndex);
});
}
Run Code Online (Sandbox Code Playgroud)
所以看起来 trackBy 和这个 sort 函数由于某种原因存在冲突。现在的结果是,当我使用 sort 函数时,items 数组会根据 z-index 进行排序,但 item 也会切换位置,这意味着它们的维度属性由于某种原因而切换。 …
假设我正在ng-repeat结束images,这是一个具有a src和caption属性的对象数组.
var images = [
{src: 'a.jpg', caption: 'a'},
{src: 'b.jpg', caption: 'b'},
{src: 'c.jpg', caption: 'c'},
{src: 'd.jpg', caption: 'd'},
{src: 'e.jpg', caption: 'e'},
{src: 'f.jpg', caption: 'f'},
{src: 'g.jpg', caption: 'g'},
{src: 'h.jpg', caption: 'h'},
{src: 'i.jpg', caption: 'i'},
{src: 'j.jpg', caption: 'j'},
];
Run Code Online (Sandbox Code Playgroud)
假设可能存在重复的图像,因此src+ caption组合不能确保唯一性.我想track by,但似乎除了之外没有办法做到这一点$index.
$index对我来说似乎是一个糟糕的解决方案 想象一下,第一张图片(a)被删除了.然后将改变所有后续图像的索引,因此必须重新渲染整个列表.这对于10个项目的列表来说并不算太糟糕,但它有更大的列表.
思考?
此外,如果确保src+ caption 是唯一的,该怎么办?我怎么能track by多个属性?
是否track by …