angular - 如何在不更改 @Input 引用的情况下使用 OnPush 策略更新 Angular UI?
问题描述
我有一个具体的组件,它用一个 @Input() 扩展了一个抽象类data
。PrimeNGdata
表使用@Input 来显示行。PrimeNG 表使用 Angular OnPush 策略。
当我将对象推送到 @Inputdata
数组时,更改不会反映在 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 表value
属性绑定到返回所有预期数据的函数可以解决 UI 不更新的问题。
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);
}
组件模板片段:
<p-table #dt [columns]="cols"
[value]="getData()"
[paginator]="true"
[paginatorPosition]="'both'"
[rows]="10">
...
推荐阅读
- reactjs - typeError:无法在 React 中读取 null 的属性“用户”
- javascript - jQuery DataTables 的下拉框中未触发 jQuery Change() 方法
- rest - 使用 jmeter 更改所有 api 请求标头中的一个变量
- kubernetes - kubectl 补丁请求抛出“此上下文中不允许映射值”
- c++ - std::sort 比自定义 OpenMP 并行排序算法快得多
- javascript - Javascript如何将对象中的空值/未定义值设置为空字符串
- hive - 在 Hive 中查找数据块
- amazon-web-services - SageMaker BlazingText 导入 FastText 模型并继续训练
- javascript - 创建文本节点并添加 CSS
- mysql - 如何将 MySQL 数据库从一个版本的 MAMP 导入到另一个版本?