使用angular2中的动态组件加载器进行双向数据绑定

时间:2016-07-11 12:23:33

标签: javascript typescript angular

我想知道如何在angular2.for中为使用动态组件加载器加载的组件建立双向数据绑定。

var result = jobs.GroupBy(x => x.OrderDetailId)
                 .Select(group => new {
                                          // You can take the first if they are equivalent.
                                          Value = group.First(),
                                          PrintedCount = group.Sum(g => g.PrintedCount)
                                      });

所以如果在动态加载的组件中对componentModel进行更改,它们也应该反映在通用组件中。反之亦然。 任何输入?

1 个答案:

答案 0 :(得分:1)

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.