Angular 如何对集合级别的变化进行自动变化检测?

问题描述

我认为 Angular 不会检测到集合级别的数据变化(例如,当一个新元素被添加一个数组时) 但就我而言,Angular 确实检测到我的情况下的集合级别变化,我不知道为什么会这样。下面是我的代码

// TableComponent's template

<tr *ngFor="let item of getProducts()">
   ...
</tr>

组件就像:

export class TableComponent {

    constructor(private model: Model) { }  // model is injected

    getProducts(): Product[] {
        return this.model.getProducts();
    }
    ...
}

一个组件通过调用 submitForm 来设法添加一个产品:

export class FormComponent {
    product: Product = new Product();

    constructor(private model: Model) { }  // model is injected

    submitForm(form: NgForm) {
        if (form.valid) {
            this.model.saveProduct(this.product);
            this.product = new Product();
            form.reset();
        }
    }
}

因此,当我在表单上添加新产品时,我希望该表不会自动将新产品添加到视图中,因为 getProducts() 中的 <tr *ngFor="let item of getProducts()"> 返回一个产品数组,当一个新的产品被添加到数组集合中,角度不应该自动检测它,但为什么在我的情况下我仍然可以看到表格自动更改(插入新行)以反映添加了新产品?

解决方法

我需要查看您使用 ngFor 的 HTML 模板的整个组件。

您是否可能正在使用以下内容:

changeDetection: ChangeDetectionStrategy.OnPush
,

将您的 html 绑定到一个函数是不好的做法,就像您在此处使用 getProducts() 所做的那样: *ngFor="let item of getProducts()" 这样做的原因是angular无法检测函数是否发生了变化,因此每次都必须重新运行该函数。

更好的方法是拥有某种财产、前产品,并做一些类似 product = this.getProducts() 的事情,或者甚至去掉中间人并拥有 product = this.model.getProducts();。然后,在您的 HTML 中绑定到 products。这将提高性能,并防止检测到更改。

总之,把你的代码改成这样:

ts:

products: Product[];
...
this.products= this.model.getProducts();

HTML:

<tr *ngFor="let item of products">

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...