我有2个嵌套组件。一个是父级( AppComponent ),另一个是子级( TooltipComponent )。两个组件都使用OnPush
更改检测。现在,无论何时更改父组件的代码,我都想更新子组件视图。我正在传递对孩子输入的新引用,但它不会更新视图。
我可以通过执行以下操作来更新子视图:
detectchanges()
或markforcheck()
,则子视图将更新。根据OnPush文档,我应该能够简单地通过将新引用传递给其输入变量来更新子视图。请让我知道我是否在这里丢失任何东西。
import { Component, OnChanges, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { timer } from 'rxjs';
@Component({
selector: 'app-root',
template: `
<tooltip [input]="childInput"></tooltip>
<button (click)="onClick()" >Trigger change detection</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent implements OnChanges {
constructor(private cd: ChangeDetectorRef){ }
childInput = {
time: new Date()
};
ngOnChanges() {
console.log('App component on changes.');
}
onClick() {
timer(1000).subscribe(sub => {
this.childInput = {
time: new Date()
};
});
}
}
import { Component, ChangeDetectionStrategy, Input, OnChanges, SimpleChange, SimpleChanges, Output, ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'tooltip',
template: `
<h1>{{input.time}}</h1>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TooltipComponent implements OnChanges {
constructor(private cd: ChangeDetectorRef,) {}
@Input() input;
ngOnChanges(){
console.log('tooltip on changes called');
}
}
答案 0 :(得分:0)
不会触发更改检测,因为仅输入对象中的一个值发生了更改,而不是对象本身。
如果您只有一个简单的属性,最好将其直接用作输入(例如,只有时间而不是包含时间的对象)。
如果您有一个对象并且只需要更改一个属性,则可以使用Object.assign({},NEW_OBJ),其中NEW_OBJ是您设置了新时间的修改对象。这样,您可以确保对象引用发生更改,并且changeDetection被触发。
看看here。尤其是“了解可变性”部分。
更新
我做了一个Stackblitz来告诉你,我的意思。如果您为输入创建新对象,则无需调用changeDetection本身。
答案 1 :(得分:0)
@ R.Richards是正确的-OnPush
中不应包含AppComponent
,因为这是应用程序的根组件,更改检测需要从某个地方开始,而AppComponent
是其中的地方它发生了。为了使您的测试更具可测量性,您应该使用AppComponent
,ParentComponent
和ChildComponent
-AppComponent
以外的所有元素,并且ChangeDetection
设置为OnPush
。
此代码:
this.childInput = {
time: new Date()
};
更新AppComponent类中的childInput
,但不更新其模板中的@Input()
。因此,您永远不会更新子组件childInput
。
如果要使其工作,则需要在更新AppComponent
类中的this.childInput = {
time: new Date()
this.cd.detectChanges()
};
之后添加一行,以便其模板将获得新的绑定,然后将其传递给子代组件。
{{1}}