How to provide a parent's model to a dynamically loaded child component in angular 2?

I have many directives built in an Angular 1.x application. Those directives are used by various internal applications at my company. I’d like for those applications to not have to change their code, but instead abstract many of those syntax changes within my directives as I upgrade to Angular 2.x.
For example let’s say I have the following directive:

<my-directive
    my-first-attribute="vm.someProperty" 
    my-second-attribute="vm.someFunction()"
></my-directive>

Assume I can’t change that syntax from the parent component’s perspective
Those attributes need to be transformed to something like:

[myFirstAttribute]="vm.someProperty"
(click)="vm.someFunction()"

There used to be a compile function where I could make many of these template changes before linking. Now I’ve got my constructor function where I can pull in an ElementRef, and DynamicComponentLoader

However, how can I provide vm to my dynamically loaded component?

I’ve tried:

this._loader.loadIntoLocation(SubCmp, this._el, 'container')
.then((compRef:ComponentRef) => {
  compRef.instance.vm = this.vm;
});

but the component that leverages DynamicComponentLoader itself doesn’t know about the vm. I really don’t want to change the HTML syntax that invokes the component which in turns dynamically loads its own child components. Here is my current plunkr, which is using Angular 2 beta 15.

2
Leave a Reply

avatar
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

The reason is that you forgot brackets []: [model]="model.firstName" If we forget the brackets, Angular treats the string as a constant and initializes the target property with that string. It does not evaluate the string! see doc, plunkr Assuming you can not change templates there are no clean ways to fulfill your requirements. I would not recommend using it, but i wanted to try angular-expressions library, check this plunkr Idea is to get parent context through injector hierarchy and parse expressions manually. //i don't fully understand why component index is 0 var context = injector.parent.getAt(0); //create parser for this.model expression,… Read more »

Jason
Guest

For communication with components added by DCL using a shared service is usually the way to go. Some ancestor provides the service and the DCL-added component injects it

@Injectable()
class Model {
  value:string = 'xxx';
}
export class InputCmp {
  constructor(private model:Model){}
  ...
}
@Component({
    selector: 'textbox',
...
    providers: [Model]
})
export class Textbox implements OnInit {
  ...
}

Plunker example