Reputation: 4421
I have followed the tutorial over at https://angular.io/docs/ts/latest/cookbook/dynamic-component-loader.html and it´s working just fine :)
Now I would like to do it a bit more advanced. http://plnkr.co/edit/D1q7Al60m4UK1weRlcmQ?p=preview
What I want is that clicking on a name should open up the details underneath on a separate row.
eg. clicking on "Luke Skywalker" or "C3PO" should create a row between the first and second row and show the details.
I have tried to dynamically add the "product-host" attribute but not working as the directive expects the attributes to exists.
<div *ngFor="let person of persons.results" fxFlex="50%" fxFlex.gt-sm="33%" person-host>
Upvotes: 2
Views: 839
Reputation: 214057
I would use ViewChildren
to achieve it. There are two possible ways:
1) Just pass index in your showPerson
function
template
<div *ngFor="let person of persons.results; let i = index" fxFlex="50%" fxFlex.gt-sm="33%" person-host>
<md-card (click)="showPerson(person, i)">{{person.name}}</md-card>
</div>
and then use it to determine desired place for info card
component
activatedViewContainerRef: ViewContainerRef;
@ViewChildren(PersonInjectorDirective) personHosts: QueryList<PersonInjectorDirective>;
loadPerson(person, index) {
if(this.activatedViewContainerRef) {
this.activatedViewContainerRef.clear();
}
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(PersonComponent);
this.activatedViewContainerRef = this.personHosts.find((item, i) => i === index).viewContainerRef;
let componentRef = this.activatedViewContainerRef.createComponent(componentFactory);
(<PersonComponent>componentRef.instance).person = person;
}
showPerson(person, index: number) {
this.loadPerson(person, index % 2 ? index : index + 1);
}
ngOnDestroy() {
if(this.activatedViewContainerRef) {
this.activatedViewContainerRef.clear();
}
}
2) You can also build it without PersonInjectorDirective
. In this case you need to declare template variable (#refs
):
<div *ngFor="let person of persons.results; let i = index" fxFlex="50%" fxFlex.gt-sm="33%" #refs>
<md-card (click)="showPerson(person, i)">{{person.name}}</md-card>
</div>
and change ViewChildren
expression as follows:
@ViewChildren('refs', { read: ViewContainerRef}) personHosts: QueryList<ViewContainerRef>;
Upvotes: 3