I have a parent component that dynamically adds child components
@Component({
selector: 'app-parent',
template: `<p>Parent:</p><ng-container #dynamic></ng-container>`
})
export class ParentComponent implements OnInit {
@ViewChild('dynamic', { read: ViewContainerRef }) vcr: ViewContainerRef;
constructor(private fr: ComponentFactoryResolver) {
}
ngOnInit() {
const factory = this.fr.resolveComponentFactory(HelloComponent);
const ref = this.vcr.createComponent(factory);
ref.instance.name = 'World';
}
}
And the child component is as follows
@Component({
selector: 'hello',
template: `<h1>Hello {{name}}!</h1>`
})
export class HelloComponent {
@Input() name: string;
}
When I change the value of name on click of a button (ref.instance.name='Bird') it doesn't update the child component view with the new value of name. I tried ref.changeDetectorRef.detectChanges() as well but even that doesn't update the child component view. I read articles online which said that changeDetectorRef.detectChanges() runs on the host view not on the component itself.
How do I update the child component view when the value of name variable changes?
After you update inputs call ref.changeDetectorRef.detectChanges();
to trigger change detection
ngOnInit() {
const factory = this.fr.resolveComponentFactory(HelloComponent);
const ref = this.vcr.createComponent(factory);
ref.instance.name = 'World';
ref.changeDetectorRef.detectChanges();
}
View related manipulation should be done only inside or after ngAfterViewInit is called. I tried your sample and moved your code to ngAfterViewInit method and it started working.
@Component({
selector: 'app-root',
template: `<p>Parent:</p><ng-container #dynamic></ng-container>`,
styleUrls: ['./app.component.less']
})
export class AppComponent implements AfterViewInit {
title = 'dynamic-child';
@ViewChild('dynamic', { read: ViewContainerRef }) vcr: ViewContainerRef;
constructor(private fr: ComponentFactoryResolver) {
}
ngAfterViewInit(): void {
const factory = this.fr.resolveComponentFactory(HelloComponent);
const ref = this.vcr.createComponent(factory);
ref.instance.name = 'World';
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.