Angular中IterableDiffers与异步输入结合失效问题咨询
解决Angular异步输入下IterableDiffers的正确使用方式
问题根源在于构造函数执行时,@Input绑定的items还未被赋值(Angular组件生命周期中,@Input属性要到ngOnInit阶段才会完成初始绑定),此时this.items为undefined,调用iterableDiffers.find(undefined)会直接抛出异常。
以下是两种无需订阅Observable的正确实现方案:
方案一:在ngOnInit中初始化IterableDiffer
利用ngOnInit钩子(组件初始化后第一个能访问到@Input属性的生命周期阶段)创建differ,同时处理items初始为undefined的情况:
export class ListComponent implements DoCheck, OnInit { @Input() items: ListItem[]; listUpdated: IterableDiffer<ListItem>; constructor(private iterableDiffers: IterableDiffers) {} ngOnInit() { // 用空数组兜底,避免find方法因传入undefined报错 this.listUpdated = this.iterableDiffers.find(this.items || []).create(); } ngDoCheck() { // 先判断differ和items是否有效,避免空指针 if (this.listUpdated && this.items) { const changes = this.listUpdated.diff(this.items); if (changes) { console.log('items changed'); } } } }
方案二:通过@Input setter初始化IterableDiffer
用setter监听items的赋值动作,仅当items首次传入有效值时创建differ,适配动态变化的场景:
export class ListComponent implements DoCheck { private _items: ListItem[]; listUpdated: IterableDiffer<ListItem>; constructor(private iterableDiffers: IterableDiffers) {} @Input() set items(value: ListItem[]) { this._items = value; // 仅当differ未创建且传入有效值时初始化 if (!this.listUpdated && value) { this.listUpdated = this.iterableDiffers.find(value).create(); } } get items(): ListItem[] { return this._items; } ngDoCheck() { if (this.listUpdated && this.items) { const changes = this.listUpdated.diff(this.items); if (changes) { console.log('items changed'); } } } }
额外注意事项
- 无论哪种方案,都要在
ngDoCheck中先判断listUpdated和items的有效性,避免空指针异常 - 如果需要处理
items从有值变为null/undefined的场景,可以在ngDoCheck中添加额外逻辑执行清理操作 IterableDiffers.find()要求传入可迭代对象,因此必须处理items为null/undefined的情况,要么用空数组兜底,要么提前判断
内容的提问来源于stack exchange,提问作者Babulaas
相关产品推荐
相关产品推荐

