【问题标题】:ngOnChanges is not called but the view is updated correctlyngOnChanges 未被调用,但视图已正确更新
【发布时间】:2020-06-17 05:25:49
【问题描述】:

我有一个与以下代码相关的问题:

孩子

export class ChildComponent implements OnChanges {
    public @Input() data: string[];

    ngOnChanges(changes: SimpleChanges) {
        console.log('I am here');
    }
}

子模板

{{ data | json }} // This is not necessary. The behaviour is the same with or without it.

<div *ngFor="let item of data">
    {{ item }}
</div>

父母

export class AppComponent implements OnInit {
    public test: string[] = ['hello'];

    ngOnInit() {
        console.log('I am here');
    }

    public addItem() {
        this.test.push('sample');
    }
}

父模板

<child-component [data]="test"></child-component>
<button (click)="addItem()">Add</button>

我知道 ngOnChanges 只会在数组引用发生变化时被调用,如果我将一个元素推送到数组中,它将不会被调用。以下引起了我的注意。当我按下添加按钮时,一个新元素被添加到数组中并且视图被正确更新。我使用 json 管道和 ngFor 来证明它更新正确。如果我不使用 json 管道,行为是一样的。那么,如果视图更新正确,为什么不调用 ngOnChanges 呢?谁负责检测是否有更改显示在视图中?

综上,疑点如下。为什么当一个元素添加到数组中时,视图会正确更新,但为什么没有调用 ngOnChanges?

变化检测的方式不同?

【问题讨论】:

    标签: angular angular2-changedetection angular-lifecycle-hooks ngonchanges


    【解决方案1】:

    您可能很清楚ngOnChanges 旨在处理@Input() 属性中的任何更改(以防将新数据简单地馈送到组件可能会产生一些额外的影响,并且无法通过组合@987654329 来完成@ 和 @Input())。所以它只关注@Input() 的变化。此外,正如您所知道的,仅当参考即将更改时才会更新。

    你的组件还是会更新,因为:

    • 您并没有告诉组件仅使用 OnPush 更改检测策略(因此它不仅会在任何 @Input() 或任何可观察/事件的引用更改上发生更改)
    • 此外(这是这里的关键)您的子视图中有一个 inpure 管道。在这里,我发现了一些关于脏管道的问题,我认为它应该回答你的问题:link(因为json 管道不纯 - docs)。尝试删除它,看看会发生什么。

    请接受这只是一个理论的事实。但我很确定这是对的。

    编辑:哦,似乎官方文档here中有一个完美的例子:

    ...当你添加英雄时,飞行英雄会显示更新,即使你改变了英雄数组。

    【讨论】:

    • 感谢您的回答。有一件事,我认为最后一个链接不正确,因为它导致了 Json Pipe 文档。你能分享正确的链接吗? :) 相对于此,即使你删除了 json 管道,ngFor 也能正常工作,也就是说,它会更新视图中的信息。行为与 json 管道相同或没有它。那么,视图中的更改检测是否比@Input (ngOnChanges) 中的多?提前致谢。
    • 是的,抱歉,链接已更新。至于问题,我创建了一个example,但老实说我不知道​​答案。我认为这是由于管道触发视图更改。也许我会找到一些东西,但这是我知识的极限。
    • Angular 也会寻找数据绑定值的变化。这就是我们所知道的。我猜 Angular 会更新视图,因为它的一些绑定值发生了变化,所以也许它足够清晰,可以将 *ngFor 解释为一组单独的绑定 {{ data[0] }}[{{ data[1] }}、...(正如我在示例中尝试的那样)。我只找到了thisthis
    猜你喜欢
    • 2022-06-11
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多