Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular dynamic component property binding

I have created a dynamic component in Angular 6 with componentFactoryResolver, and I need to update one of its properties every 3 seconds.

const componentFactory = this.cfr.resolveComponentFactory(componentType);
const component: ComponentRef<any> = vcr.createComponent(componentFactory);

component.instance.property = this.newData;

    setInterval(() => {
      this.loadNewData().then((data) => {
        this.newData = data;
      });
    }, 3000);

The property is not getting updated. I found out that dynamically generated components do not support property binding. So, how can I update the property with the new data? Is there any workaround for this?

like image 866
Emanuel T Avatar asked Sep 19 '25 04:09

Emanuel T


2 Answers

A bit late but I found your question interesting... :)

I made a Stackblitz example: https://stackblitz.com/edit/angular-3gvrrz

As I wasn't completely sure about your requirements I made the example using @Input() and using a BehaviorSubject in a shared service.

export class AppComponent implements OnInit {
  name = 'Angular';
  @ViewChild(ContainerDirective, { static: true }) container: ContainerDirective;
  DATA = ['Angular', 'Material', 'Nativescript', 'Ionic'];
  index = 0;

  constructor(private componentFactoryResolver: ComponentFactoryResolver,
    private commonService: CommonService) {}

  ngOnInit() {
    const viewContainerRef = this.container.viewContainerRef;
    viewContainerRef.clear();
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(HelloComponent);
    const componentRef = viewContainerRef.createComponent(componentFactory);
    (<HelloComponent>componentRef.instance).name = 'Starting...';

    setInterval(() => {
      if (this.index > this.DATA.length - 1) {
        this.index = 0;
      }
      const nextName: string = this.DATA[this.index++];
      (<HelloComponent>componentRef.instance).name = nextName;
      this.commonService.setName(nextName)
    }, 3000);
  }
}
like image 72
Kari F. Avatar answered Sep 20 '25 20:09

Kari F.


Use ng-interconnect for communication in these types of use cases.

  1. Create a broadcaster in your parent component

     let broadcaster = interconnect.createBroadcaster('home-messgae');   
    
  2. Receive from the broadcaster from inside the dynamic component

     interconnect.receiveFrom('home-message', '', (data) => {
        console.log('do something with ' + data);
     );
    
  3. Start emitting from the parent component

    broadcaster.emit('hello dynamic child');
    

Article: https://charlie-code.medium.com/simplify-your-angular-development-using-ng-interconnect-1b94c68e9141

like image 43
Charlie Avatar answered Sep 20 '25 18:09

Charlie