trackBy 与异步管道
Posted
技术标签:
【中文标题】trackBy 与异步管道【英文标题】:trackBy with the async pipe 【发布时间】:2017-12-01 23:29:03 【问题描述】:我正在尝试使用 async
管道和 *ngFor
来显示异步获取的项目数组。
<ul>
<li *ngFor="let item of items | async; trackBy: trackPost">
item.text
</li>
</ul>
ngOnInit()
// very simple http call; returns an array of [id: 1, text: "something"]
this.items = this.itemService.loadItems();
trackPost(index, item) return item.id;
这很好用。然后我想添加一个项目:
async addItem(text)
await this.itemService.addItem(text);
// reload items after adding
this.items = this.itemService.loadItems();
这也有效,它会在添加后正确更新项目。
问题在于它会重新加载整个数组,而不仅仅是追加项目。您可以通过动画注意到这一点(如果您为项目设置动画)。我知道我可以自己处理订阅并使用数组,但我想知道是否有办法使用异步管道来做到这一点。
有没有办法让我将新项目添加到现有的 observable 中?如果做不到这一点,有没有办法让模板正确跟踪项目,而不是将它们视为重新添加?
【问题讨论】:
面临同样的问题,进行 algolia 搜索... 如果您只是将push(newItem)
转换为this.items
,角度会不会注意到?
有人知道发生了什么以及任何解决方法吗?谢谢!
【参考方案1】:
问题是您通过this.items = this.itemService.loadItems();
重新分配了流。因此,您的 Observable items
不会发出新值,Angular 会使用您的 trackBy 函数跟踪这些值,而不是您更改 items
的引用,从而导致 Angular 进行完全重新加载。
所以只需更改您的服务的addItem
-function 以将更新的值发送到您之前通过loadItems
获得的 Observable。之后你只需调用
addItem(text)
this.itemService.addItem(text);
服务示例:
@Injectable()
export class Service
private items: Array<string> = [];
private items$ = new Subject<Array<string>>();
loadItems(): Observable<Array<string>>
return this.items$.asObservable();
addItem(text: string)
this.items = [...this.items, text];
this.items$.next(this.items);
【讨论】:
以上是关于trackBy 与异步管道的主要内容,如果未能解决你的问题,请参考以下文章