Angular createEmbeddedView with Context and Injector
May 15, 2023
On this page we will learn to use ViewContainerRef.createEmbeddedView()
method in our Angular application. Embedded views are created using <ng-template>
and is attached to the container represented by ViewContainerRef
using createEmbeddedView()
method. We can insert the view in the view container using Component as well as Directive.
The
ViewContainerRef
represents a container where one or more views can be attached to a component. It has following methods.
1. createEmbeddedView() : Instantiates an embedded view and inserts it into this container.
2. createComponent() : Instantiates a single component and inserts its host view into this container.
3. clear() : Destroys all views in this container.
4. get() : Retrieves a view from this container.
5. insert() : Inserts a view into this container.
6. move() : Moves a view to a new location in this container.
7. indexOf() : Returns the index of a view within the current container.
8. remove() : Destroys a view attached to this container
9. detach() : Detaches a view from this container without destroying it.
On this page we will learn to use
createEmbeddedView()
method with examples.
ViewContainerRef.createEmbeddedView()
Find the declaration ofcreateEmbeddedView
method from Angular doc.
1. With Injector (Introduced in Angular 14)
createEmbeddedView<C>( templateRef: TemplateRef<C>, context?: C, options?: { index?: number; injector?: Injector; } ): EmbeddedViewRef<C>
createEmbeddedView
creates embedded view and inserts into this container that returns the EmbeddedViewRef
for newly created view.
Parameters:
The templateRef is the HTML template that defines the view.
The context is the data-binding context of the embedded view as declared in
<ng-template>
. This is optional.
The options is the object for extra configuration (optional) that includes index and injector as given below.
{ index?: number; injector?: Injector; }
The injector is the
Injector
to be used within the embedded view.
2. Without Injector.
createEmbeddedView<C>( templateRef: TemplateRef<C>, context?: C, index?: number ): EmbeddedViewRef<C>
With Component
In our example we have parent and child component. In parent component we are creating html code using<ng-template>
. Within this code we are including child component. We are embeding the <ng-template>
code within <div>
element that is our view container.
app.component.html
<h3>With Component</h3> <ng-template #templateRef let-book="bookName" let-writer="writer" let-location> <span> I am from {{location}} and like to read {{book}} written by {{writer}} ji. </span> <app-student></app-student> </ng-template> <div #viewContainerRef> </div>
import { Component, ViewChild, Injector, ViewContainerRef, TemplateRef } from "@angular/core"; @Component({ selector: 'app-root', templateUrl: 'app.component.html' }) export class AppComponent { @ViewChild('viewContainerRef', { read: ViewContainerRef, static: true }) viewContainerRef!: ViewContainerRef; @ViewChild('templateRef', { read: TemplateRef, static: true }) templateRef!: TemplateRef; allStudents = [ { name: 'Mohit', age: 25 }, { name: 'Krishn', age: 30 } ]; ngOnInit() { this.viewContainerRef.createEmbeddedView(this.templateRef, { bookName: 'Ramayan', writer: 'Valmiki', $implicit: 'Prayag' }, { index: 0, injector: Injector.create({ providers: [{ provide: 'students', useValue: this.allStudents }] }) }); } }
import { Component, Inject } from "@angular/core"; import { Student } from "./student"; @Component({ selector: 'app-student', template: ` <div *ngFor="let std of students"> <p>{{std.name}} - {{std.age}}</p> </div> ` }) export class StudentComponent { constructor(@Inject('students') public students: Student[]) {} }
export interface Student { name?: String; age?: number; }
With Directive
Find the code to insert the view using Directive.app.component.html
------ <h3>With Directive</h3> <ng-container *myDir > <app-student></app-student> </ng-container>
import { Directive, ViewContainerRef, TemplateRef, Injector } from "@angular/core"; @Directive({ selector: '[myDir]' }) export class MyDirective { constructor(private vcRef: ViewContainerRef, private templateRef: TemplateRef<any>) { } allStudents = [ { name: 'Jai', age: 30 }, { name: 'Arjun', age: 35 } ]; ngOnInit() { this.vcRef.createEmbeddedView(this.templateRef, {}, { injector: Injector.create({ providers: [{ provide: 'students', useValue: this.allStudents }] }) }) } }
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { StudentComponent } from './student.component'; import { MyDirective } from './my.directive'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent, StudentComponent, MyDirective ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
