Octavian Niculescu
Octavian Niculescu

Reputation: 445

Trying to learn Angular using a video course - stuck with ViewContainerRef & TemplateRef

As the title says, I've been trying (and succeeding so far) to learn Angular, until I got into structural directives.

I had to create my own using TemplateRef and ViewContainerRef.

The course teacher did it like this:

import { Directive, TemplateRef, Input, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appUnless]'
})
export class UnlessDirective {
  @Input() set appUnless(condition: boolean)
  {
    if(!condition)
    {
      console.log(this.templateRef);
      console.log(this.vcRef);
      this.vcRef.createEmbeddedView(this.templateRef);
    }
    else
    {
      console.log(this.templateRef);
      console.log(this.vcRef);
      this.vcRef.clear();
    }
  }

  constructor(private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef) { }

}

<div class="container">
  <div class="row">
    <div class="col-xs-12">
      <button
        class="btn btn-primary"
        (click)="onlyOdd = !onlyOdd">Only show odd numbers</button>
      <br><br>
      <ul class="list-group" *appUnless="onlyOdd">
        <li
          class="list-group-item" *ngFor="let number of numbers">
          {{number}}
        </li>
      </ul>
      <ng-template>
        <p>Only odd</p>
      </ng-template>
    </div>
  </div>
</div>

The console.log lines are inserted by me so I can see what's happening.

Unfortunately, I just can't figure out how this code works.

I've also been trying using Angular docs but I don't really seem to get it.

What I've understood so far (I'm not sure that it's right) is that TemplateRef is just a reference for the that will be created from the * in the Directive, and ViewContainerRef either displays it or not, through methods such as createEmbeddedView() or clear().

Can anybody explain to me in-depth what the code does, mostly TemplateRef and ViewContainerRef? Thanks.

Upvotes: 0

Views: 81

Answers (1)

j4rey
j4rey

Reputation: 2677

Structural directives are responsible for HTML layout. They shape or reshape the DOM's structure, typically by adding, removing, or manipulating elements.

In simple terms, TemplateRef is the reference to the template, ie the view (in your case, it's the ul) where you've attached the directive.

And the ViewContainerRef, as the name suggest, is the container which will hold your view.

And you'd basically toggle (attach and remove) the template (view) from the container i.e., the DOM.

Something like so:

...
<button class="btn btn-primary" (click)="onlyOdd = !onlyOdd">Only show odd numbers</button>
<br><br>
<ng-container> <--- your view container
    <ul>   <-- your template
        ...
    </ul>
<ng-container>
<ng-template>
    <p>Only odd</p>
</ng-template>
...

Upvotes: 2

Related Questions