【问题标题】:trackBy with the async pipetrackBy 与异步管道
【发布时间】: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,角度会不会注意到?
  • 有人知道发生了什么以及任何解决方法吗?谢谢!

标签: javascript angular typescript asynchronous rxjs


【解决方案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);
    }
}

【讨论】:

    猜你喜欢
    • 2020-01-15
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多