2

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)
}

1 Answer 1

1

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.

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

1 Comment

this.lastCreatedViewContainerRef = vc; should be: OutlerDirective.lastCreatedViewContainerRef = vc;

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.