简体   繁体   English

Angular2:使用DynamicComponentLoader动态插入的组件上的双向数据绑定

[英]Angular2: Two-way data binding on component dynamically inserted using DynamicComponentLoader

I am developing an Angular2 app, and I faced a problem: 我正在开发一个Angular2应用程序,我遇到了一个问题:

I have a set of different objects that can be selected using UI. 我有一组可以使用UI选择的不同对象。 Each of this objects has a set of options (different for different objects) that could be edited using UI. 每个对象都有一组可以使用UI编辑的选项(不同对象不同)。 Now, I am using DynamicComponentLoader to insert a specific component for currently selected object, so it can handle its options correctly. 现在,我正在使用DynamicComponentLoader为当前选定的对象插入特定组件,因此它可以正确处理其选项。 The problem is that I don't know how to bind data of currently selected object to a dynamically inserted options component. 问题是我不知道如何将当前所选对象的数据绑定到动态插入的选项组件。

@Component({
  selector: 'dynamic',
  template: `<div>Options:</div>
             <div>Property1: <input type="number" /></div>
             <div>Property2: <input type="text" /></div>`
  // template: `<div>Options:</div>
  //           <div>Property1: <input type="number" [(ng-model)]="currentSelection.property1" /></div>
  //           <div>Property2: <input type="text" [(ng-model)]="currentSelection.property1" /></div>`
})
class DynamicComponent {

}


@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Selected: {{currentSelection.name}}!</h2>
      <div  #container></div>
    </div>
  `
})
class App {
  currentSelection = {name: 'Selection1', property1: 10, property2: 'test'};

  constructor(private loader: DynamicComponentLoader, private elementRef: ElementRef) {
    loader.loadIntoLocation(DynamicComponent, elementRef, 'container');
  }
}

Here is a plunker to help you understand my question: 是一个帮助您理解我的问题的plunker:

With angular2 and Rxjs, " Observables " are almost always the answer. 对于angular2和Rxjs,“ Observables ”几乎总是答案。

If i understood your problem correctly, you need to make your DynamicComponent an " Observer " and your container "an Observable or even better a Subject (In case your container needs to subscribe to another observable to receive selections from)". 如果我正确地理解了你的问题,你需要让你的DynamicComponent成为一个“ Observer ”,你的容器是一个Observable甚至更好的一个Subject (如果你的容器需要订阅另一个observable来接收选择)“。 Then, after loading your dynamic component, subscribe it to your container. 然后,在加载动态组件后,将其订阅到您的容器。

Whenever the selection changes on your container, you push the new selection to your subscribers. 只要容器上的选择发生变化,您就可以将新选择推送给订阅者。 This way, you can load multiple dynamic components and all will receive your pushes. 这样,您可以加载多个动态组件,并且所有组件都将接收您的推送。

The Container: 容器:

class App {
  currentSelection = {};
  selections = [
    {name: 'Selection1', property1: 10, property2: 'test'},
    {name: 'Selection2', property1: 20, property2: 'test2'}
  ];
  subject:Subject<any> = new Subject();

  constructor(private loader: DynamicComponentLoader, private elementRef: ElementRef) {
  }

  ngOnInit(){
    this.loader.loadIntoLocation(DynamicComponent, this.elementRef, 'container', this.injector)
    .then(compRef =>this.subject.subscribe(compRef.instance));
    // subscribe after loading the dynamicComponent
  }

  // set the new selection and push it to subscribers
  changeSelection(newSelection){
    this.currentSelection = newSelection;
    this.subject.next(this.currentSelection);
  }
}

The Observer: 观察员:

class DynamicComponent implements Observer{
  public currentSelection = {};

  next(newSelection){
    this.currentSelection = newSelection;
  }
}

Here is your plunker working after my edits, "provided I changed the imports to the newest angular beta.6" 这里是你的plunker我的编辑工作后,“提供我改变了进口最新的角beta.6”

I know this is a quite old question. 我知道这是一个很老的问题。 But hopefully someone will benefit from this answer. 但希望有人能从这个答案中受益。

Here is what you can do, move your code from constructor to ngOnInit and use promises for assigning dynamic value. 您可以执行以下操作,将代码从constructor移动到ngOnInit并使用promises分配动态值。

ngOnInit(){
    this.dynamicComponentLoader.loadIntoLocation(DynamicComponent, this.elementRef,'container').then((component)=>{
        component.instance.currentSelection = currentSelection;
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM