14

I am developing an Angular2 app, and I faced a problem:

I have a set of different objects that can be selected using UI. Each of this objects has a set of options (different for different objects) that could be edited using UI. Now, I am using DynamicComponentLoader to insert a specific component for currently selected object, so it can handle its options correctly. 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:

1

2 Answers 2

4

With angular2 and Rxjs, "Observables" are almost always the answer.

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)". 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"

I know this is a quite old question. But hopefully someone will benefit from this answer.

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

Comments

2

Here is what you can do, move your code from constructor to ngOnInit and use promises for assigning dynamic value.

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

Comments

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.