Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass @Input() params to an angular 2 component created with DynamicComponentLoader

Tags:

angular

The DynamicContentLoader docs don't explain how I can properly load a child component's inputs. Let's say I have a child like:

@Component({
  selector: 'child-component',
  template: '<input type="text" [(ngModel)]="thing.Name" />'
})
class ChildComponent {
  @Input() thing : any;
}

and a parent like:

@Component({
  selector: 'my-app',
  template: 'Parent (<div #child></div>)'
})
class MyApp {
  thing : any;
  constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
    dcl.loadIntoLocation(ChildComponent, elementRef, 'child');
  }
}

How should I go about passing thing into the child component such that the two components can be data bound against the same thing.

I tried to do this:

@Component({
  selector: 'my-app',
  template: 'Parent (<div #child></div>)'
})
class MyApp {
  thing : any;
  constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
    dcl.loadIntoLocation(ChildComponent, elementRef, 'child').then(ref => {
        ref.instance.thing = this.thing;
    });
  }
}

It sort of works, but they are not synchronised as you would expect.

Basically I am trying to achieve the same thing that would have been achieved by using ng-include in angular 1 where the child is a dynamically determined component and shares the model with its parent.

Thanks in advance ...

like image 839
Julian Jelfs Avatar asked Jan 06 '16 14:01

Julian Jelfs


1 Answers

I made some tests for your problem and I can't reproduce it.

Here is the content of my child component:

@Component({
  selector: 'child-component',
  template: `
    <div>
      Child component - <input type="text" [(ngModel)]="thing.name" />
    </div>
  `
})
export class ChildComponent {
  @Input() thing : any;

  constructor() {
  }
}

Here is the content of the parent component:

@Component({
  selector: 'my-dyn-parent',
  template: `
    <div>
      Parent component - <input type="text" [(ngModel)]="thing.name" /> (<br/>
        <div #child></div>
      <br/>)
    </div>
  `
})
export class ParentComponent {
  thing : any;
  constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
    this.thing = { name: 'test name' };
    dcl.loadIntoLocation(ChildComponent, elementRef, 'child')
                     .then((compRef:ComponentRef) => {
      compRef.instance.thing = this.thing;
    });
  }
}

So I have two inputs bound on the same element: one within the parent component and one in the child one. When I update the value in one input, the other value is updated in the other input.

So both components share the same instance and can update it. Perhaps I missed something in your use case, so feel free to tell me!

Hope it helps you, Thierry

like image 134
Thierry Templier Avatar answered Oct 21 '22 20:10

Thierry Templier