问题描述
我有一个具体的组件,它用一个@input() data
扩展了一个抽象类。 PrimeNG 表使用@Input data
来显示行。 PrimeNG 表使用 Angular OnPush 策略。
当我将对象推送到@Input data
数组时,更改不会反映在 UI 中。
如果在将对象推送到数组后更改 data
的引用(通过类似 this.data = deepcopy(this.data) as Field[]),则更改将显示在 UI 中。
在这种情况下,我不希望更改 data
的引用,因为其他组件可能会操纵该数据,而且我不希望同步同一数据的多个不同副本。
如何在不更改引用的情况下强制 Angular 更新 UI? ChangeDetectorRef.detectChanges() 不会相应地更新 UI。
带有 PrimeNG 表的抽象表类:
@Directive()
export abstract class TableComponent<T> implements OnChanges {
@input() data: T[];
@ViewChild('dt') dataTable: Table; // PrimeNG table which displays rows of data
...
}
具有 addRow() 函数的具体类:
@Component({
selector: 'app-table',templateUrl: '...',styleUrls: ['...']
})
export class SomeComponent extends TableComponent<Field> implements OnInit,OnChanges {
...
public addRow(): void {
const field = {} as Field;
field.id = 1;
this.data.push(field);
// this.changeDetectorRef.detectChanges(); // Does not update the UI
// this.data = deepcopy(this.data) as Field[]; // Updates the UI by changing reference
}
}
解决方法
我想出了一个让 UI 正确更新的解决方案。
将 PrimeNG 表 list_ports
属性绑定到返回所有预期数据的函数可解决 UI 未更新的问题。
value
组件模板片段:
public addRow(): void {
const field = {} as Field;
field.id = 1;
this.data.push(field);
}
public getData(): Field[] {
return this.data.filter(field => field.id > 0);
}