i have a definition of templates in my angular app:
<div class="wrapper" grid [data]="data">
<div class="cell" *cellDef="let cell">{{cell.id}}</col>
<div class="row" *rowDef="let row"></div>
</div>
Right now I create "rows" in a directive based on some data injected to wrapper. I create for example 10 rows by creating embeddedViews with templateRef and viewContainerRef of rowDef.
Same for cells, but I want to render cells inside of the rows viewRef. My problem right now is, that I am not able to get the viewContainerRef of the embedded TR Element created by rowDef.
Attaching another directive (non-strucural) let me inject the viewContainerRef, but it only gave me the viewContainerRef where the tr is rendered. How can I get the viewContainerRef inside the tr element to attach the cells to?
<div class="row" *rowDef="let row" non-structural-directive></div>
@Directive({selector: '[non-structural-directive]'})
export class NonStructuralDirective {
// points to "wrapper" instead of "row" so it isn't helpful at all
constructor(vc:ViewContainerRef)
}
For those interested into the solution...
In the end it was really simple and already solved by cdk-table. So it was not my solution neither my idea. (By the way, it is simply brilliant how it was designed)
I've created a component which uses my non-structural-directive as selector. Also I used an ng-container with another directive where I can get the viewContainerRef when it gets rendered.
/**
* this is the missing piece. You can use components
* to select directives and html tags and add html to it.
* by adding ng-container with another directive we are
* now able to reference viewContainerRef of the inner
* tr element
*/
@Component({
selector: 'non-structural-directive, tr[non-structural-directive]',
template: '<ng-container outlet>/<ng-container>'
})
export class StructuralComponent {}
/**
* will be created after tr was embedded
* provides handle for referencing viewContainerRef inside of tr element
*/
@Directive({
selector: 'outlet'
})
export class OutletDirective {
static lastCreatedViewContainerRef:ViewContainerRef;
constructor(vc:ViewContainerRef) {
OutletDirective.lastCreatedViewContainerRef = vc;
}
}
For the Outlet Directive it is important to provide a static variable to store the latest created viewContainerRef, otherwise I will not know where it belongs to. If someone needs further explaination, feel free to respond, I will extend my answer.