我正在使用Angular 6而我已经尝试按照here的说法进行操作但是我无法使用它
export class AppComponent implements AfterContentInit, AfterViewInit {
defaultToTrue = true;
@ViewChildren('parent', { read: ViewContainerRef }) parent: QueryList<ViewContainerRef>;
constructor(private cfr: ComponentFactoryResolver) { }
ngAfterViewInit(){
const resolve = this.cfr.resolveComponentFactory(ChildComponent);
this.parent.changes.subscribe(changes => {
this.parent.createComponent(resolve); //Error
});
}
}
HTML:
<div *ngIf="defaultToTrue">
<div #parent></div>
</div>
答案 0 :(得分:2)
要摆脱ExpressionChangedAfterItHasBeenCheckedError
,您可以使用this Angular In Depth blog post中建议的技巧之一:
使用ChangeDetectorRef.detectChanges
检测强制更改:
constructor(private cfr: ComponentFactoryResolver, private cd: ChangeDetectorRef) { }
ngAfterViewInit(){
const resolve = this.cfr.resolveComponentFactory(ChildComponent);
this.parent.changes.subscribe(changes => {
this.parent.createComponent(resolve);
this.cd.detectChanges(); // Trigger change detection
});
}
使用setTimeout
:
ngAfterViewInit(){
const resolve = this.cfr.resolveComponentFactory(ChildComponent);
this.parent.changes.subscribe(changes => {
setTimeout(() => { this.parent.createComponent(resolve); });
});
}
答案 1 :(得分:0)
我的情况是#container
位于2 *ngFor
的内部,而所有*ngIf
内部
我什至可以获取ViewContainerRef
或QueryList<ViewContainerRef>
的实例的唯一方法是在ngAfterViewChecked
中,并且仅在条件之内,甚至是在运行setTimeout
的情况下,< / p>
编辑:必须添加一个标记才能停止,否则该标记会不断运行
if (this.fieldsContainer && this.componentsGenerated == false) {
this.componentsGenerated = true
setTimeout(this.generateComponents.bind(this))
}
EDIT2:
最终需要更多的代码来处理所有这些,并将changeDetection: ChangeDetectionStrategy.OnPush
与cd:ChangeDetectorRef
ngAfterViewChecked(): void {
if (this.fieldsContainersQuery && this.componentsGenerated == false) {
this.componentsGenerated = true
this.fieldsContainersQuery.changes.subscribe(changes=>{
this.fieldsContainersQuery.forEach(fieldContainerItem => this.generateComponents(fieldContainerItem))
this.cd.detectChanges()
})
}
更多详细信息