TemplateRef

The notion of a template should be familiar for most web developers. It’s a group of DOM elements that are reused in views across the application. Before the HTML5 standard introduced the template tag, most templates arrived to the browser wrapped in a script tag with some variation of the type attribute:

<script id="tpl" type="text/template">
  <span>I am span in template</span>
</script>

This approach certainly had many drawbacks like the semantics and the necessity to manually create DOM models. With the template tag a browser parses html and creates a DOM tree but doesn’t render it. It can then be accessed through the content property:

<script>
  let tpl = document.querySelector("#tpl")
  let container = document.querySelector(".insert-after-me")
  insertAfter(container, tpl.content)
</script>
<div class="insert-after-me"></div>
<ng-template id="tpl">
  <span>I am span in template</span>
</ng-template>

Angular embraces this approach and implements TemplateRef class to work with a template. Here is how it can be used:

@Component({
  selector: "sample",
  template: `<ng-template #tpl>
    <span>I am span in template</span>
  </ng-template>`,
})


export class SampleComponent implements AfterViewInit {
  @ViewChild("tpl") tpl: TemplateRef<any>

  ngAfterViewInit() {
    let elementRef = this.tpl.elementRef
    // outputs `template bindings={}`
    console.log(elementRef.nativeElement.textContent)
  }
}

The framework removes the template element from the DOM and inserts a comment in its place. This is how it looks when rendered:

<sample>
  <!--template bindings={}-->
</sample>

By itself the TemplateRef class is a simple class. It holds a reference to its host element in the elementRef property and has one method: createEmbeddedView.

However, this method is very useful since it allows us to create a view and return a reference to it as ViewRef.

Template References

We can also have a template injected directly into our component using the ViewChild decorator:

@Component({
  selector: 'app-root',
  template: `      
      <ng-template #defaultTabButtons>
          <button class="tab-button" (click)="login()">
            {{loginText}}
          </button>
          <button class="tab-button" (click)="signUp()">
            {{signUpText}}
          </button>
      </ng-template>
`})
export class AppComponent implements OnInit {

    @ViewChild('defaultTabButtons')
    private defaultTabButtonsTpl: TemplateRef<any>;

    ngOnInit() {
        console.log(this.defaultTabButtonsTpl);
    }

}

Things that are inside ng-template component can only be grabbed and used somewhere else later. To be able to grab this template, I have given it a variable called “defaultTabButtons”.

And then going into the Component code of this file, adding the same “defaultTabButtons” variable inside ViewChild. So this ‘defaultTabButtons” acts as a hook to grab thinks inside ng-template

As we can see, the template can be injected just like any other DOM element or component, by providing the template reference name defaultTabButtons to the ViewChild decorator.

This means that templates are accessible also at the level of the component class, and we can do things such as for example pass them to child components!

An example of why we would want to do that is to create a more customizable component, where can pass to it not only a configuration parameter or configuration object: we can also pass a template as an input parameter.

Important

Sometime, we need to be able to access the code that is grabbed by the ViewChild. To do so, we are going to use a lifecycle hook called AfterViewInit.

Further Reading

https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/

https://indepth.dev/exploring-angular-dom-manipulation-techniques-using-viewcontainerref/

To Get Daily Health Newsletter

We don’t spam! Read our privacy policy for more info.

Download Mobile Apps
Follow us on Social Media
© 2012 - 2025; All rights reserved by authors. Powered by Mediarx International LTD, a subsidiary company of Rx Foundation.
RxHarun
Logo