trackBy with async pipe

时间:2017-06-28 14:20:28

标签: javascript angular typescript asynchronous rxjs

我正在尝试使用带有async的{​​{1}}管道来显示异步获取的项目数组。

*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; }

这也有效,并且在添加后会正确更新项目。

问题是它会重新加载整个数组,而不仅仅是附加项目。你可以通过动画注意到这一点(如果你动画中的项目)。我知道我可以自己处理订阅并使用数组,但我想知道是否有办法使用异步管道。

我有办法将新项添加到现有的observable中吗?如果不这样做,有没有办法让模板正确跟踪项目,而不是将它们视为重新添加?

1 个答案:

答案 0 :(得分:1)

问题是您通过this.items = this.itemService.loadItems();重新分配了流。因此,您的Observable items不会发出新值,Angular会使用您的trackBy函数跟踪,而不是更改items的引用,导致angular进行完全重新加载。

因此,只需更改服务的addItem - 功能,即可通过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);
    }
}