【发布时间】:2018-02-08 15:02:42
【问题描述】:
使用 Angular 4.3 和以下Plunkr。
请考虑以下组件:
@Component({
selector: 'my-app',
template: `
<div>
<button type="button" (click)="toggle()">Toggle</button>
<div #anchor></div>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class App {
@ViewChild('anchor', {read: ViewContainerRef}) anchor: ViewContainerRef;
dynamicRef: ComponentRef;
value = true;
constructor(private cfr: ComponentFactoryResolver, private cdr: ChangeDetectorRef) {}
ngAfterViewInit(): void {
let factory = this.cfr.resolveComponentFactory(Dynamic);
this.dynamicRef = this.anchor.createComponent(factory);
this.dynamicRef.instance.value = this.value;
this.dynamicRef.changeDetectorRef.detectChanges();
}
toggle(): void {
this.value = !this.value;
this.dynamicRef.instance.value = this.value;
this.dynamicRef.changeDetectorRef.detectChanges();
}
}
@Component({
template: `Value: {{value}}`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class Dynamic {
@Input() value = true;
}
App 组件使用标准ComponentFactoryResolver + ViewContainerRef 策略创建Dynamic 组件。这两个组件都有一个OnPush 更改检测策略。当调用App.toggle() 方法时,它会切换App.value,将这个新值传播到Dynamic.value,并强制在动态组件的更改检测器上运行更改检测。我希望动态组件的模板显示正确的值,但它实际上永远不会改变。将这两个组件切换到 Default 更改检测策略可提供预期的行为。
为什么动态组件模板没有正确重新渲染,如何解决?
【问题讨论】:
-
可能不相关:App 类缺少 AfterViewInit 实现
-
不确定你的意思,我确实在 Plunkr 和这篇文章中看到了 App.ngAfterViewInit() {...}?
-
导出类App实现AfterViewInit angular.io/api/core/AfterViewInit#how-to-use
-
是的,生命周期接口尚未添加到类声明中。我认为这与这个问题无关。
-
我就是这么说的:)
标签: angular