0

I want to know how one can establish two way data binding with components loaded using dynamic component loader in angular2.for ex.

ngAfterViewInit() {
//console.log('Generic Component...' + this.componentName + " Loading");
let componentIndex = this.keysRegister.indexOf(this.componentName);  
this.dcl.loadNextToLocation(this.typesRegister[componentIndex],this.target)
    .then(ref => { 
      ref.instance.componentModel = this.componentModel; 
    });  
console.log('Generic Component...' + this.componentName + " Loaded");
}

so if am making changes to componentModel in dynamically loaded component , they should reflect in generic component too & vice versa. any inputs?

1 Answer 1

2

First: DynamicComponentLoader is deprecated for couple of versions now, it will be private in next version or after. Look at the implementation and copy it it's quite simple. You resolve the component using ComponentResolver, this returns a factory which is used by a ViewContainer to create a component.

The main difference is that DynamicComponentLoader used a ViewContainerRef you supplied, now you directly use the ViewContainerRef instance to create a new component / template.

As for your question:

First, lets separate 2-way data binding into @Input and @Output. We must do that because they are really different in angular.

A quick answer: You need to manually manage inputs and outputs, yep.

To fully understand why we need to dive deep into the code generator and what it does, I will try to stay at the top, this takes time to process.

A note to remember: when you create a component you get an instance of ComponentRef which holds a reference to the instance of your component.

OUTPUT For outputs you need to subscribe to every EventEmitter on the instance of your newly created component, those EventEmitters are the @Output properties you declare, you also need to unsubscribe from them when at the right time, or relay on the component you just created to complete() the emitter when it gets destroyed.

INPUT For inputs you need to listen to the ngDoCheck lifecycle hook and check for every item you consider an @Input item, if it changed. Also, if you wondering about passing data to the new component via attributes, this is not possible since you don't really have a Host element, you are about to create it... so sending data to the component is done by:

  1. dependency injection using a new injector when creating the component
  2. Setting values on the instance, right after you created it (which is the same approach as subscribing to output)

Now, this is a lot right... well it is, it's a lot of boilerplate, repetitive code that you can automate... and that's exactly what angular does.

When using the template engine, a component is actually a "behind the scene" code that represents all of the above, step by step. it does all checks for you, does all subscriptions and clean up and some more... it also call's all the lifecycle hooks that are the actual interrupt points you have in your component. This is all possible since angular parses the component's template and know about [inputs] and (outputs), it also comes from metadata via @Input() and @Output... This is true for animations as well...

If you think about it, angular is an HTML to code engine that takes HTML markup mixed with code instructions written in HTML and creates JavaScript code from it. That code uses the instance of your component (which match the template) and does that magic called angular.

Sign up to request clarification or add additional context in comments.

2 Comments

I know about two-way data binding using Input() & Output() but its not useful if components are loaded using dynamicComponentLoader
Did you read all of my post? Input() and Output() are used by the templating system in angular, you want to bypass it by dynamically creating components - so you need to mimic the operation done by angular.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.