I am confused between use cases of createEmbeddedView and createComponent, i.e when to use which one.
Please come up with some cases that can tell about suitable setting to use either of them in "dynamic creation scenario".
The simplest wrapper around a DOM element is ElementRef . For templates you have TemplateRef that allows you to create an embedded view. Host views can be accessed on componentRef created using ComponentFactoryResolver . The views can be manipulated with ViewContainerRef .
It's used to create a view using TemplateRef. TemplateRef is created by Angular compiler when it encounters ng-template tag in your component html. The view created using this method is called an embedded view .
Embedded views are created from templates using TemplateRef, while host views are created using a view (component) factory. For example, the main component that is used to bootstrap an application ( AppComponent ) is represented internally as a host view attached to the component's host element ( <app-comp> ).
A TemplateRef represents an <ng-template /> . <ng-template let-name let-date="dateNow">{{date}} - Hello {{name}}!</ng-template> An <ng-template /> itself will not do anything at all. We need a ViewContainerRef to insert the template somewhere.
See this workshop on DOM manipulation or read Working with DOM in Angular: unexpected consequences and optimization techniques where I explain the difference with examples.
These both methods are used to dynamically add content to the component view (DOM). This content can be either a template or a component based. In Angular we usually manipulate the DOM using ViewContainerRef. And both these methods are available on it:
class ViewContainerRef { ... createEmbeddedView<C>(templateRef: TemplateRef<C>, context?: C, index?: number): EmbeddedViewRef<C> createComponent<C>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][], ngModule?: NgModuleRef<any>): ComponentRef<C> } To learn more about manipulating the DOM read Exploring Angular DOM manipulation techniques using ViewContainerRef.
It's used to create a view using TemplateRef. TemplateRef is created by Angular compiler when it encounters ng-template tag in your component html. The view created using this method is called an embedded view.
import { VERSION, Component, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; @Component({ selector: 'my-app', template: ` <ng-container #vc></ng-container> <ng-template #tpl> <h1>Hello, {{name}}</h1> </ng-template> `, styles: [''] }) export class AppComponent { name = `Angular! v${VERSION.full}`; @ViewChild('tpl', {read: TemplateRef}) tpl: TemplateRef<any>; @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef; ngOnInit() { this.vc.createEmbeddedView(this.tpl); } } Stackblitz demo
This approach is used by all structural directives like *ngIf and *ngFor because they are all wrap a ng-template. For example, for *ngIf the code:
<div *ngIf="data">{{name}}</div> is transformed into
<ng-template ngIf="data"> <div>{{name}}</div> And the ngIf directive uses createEmbeddedView internally:
@Directive({selector: '[ngIf]'}) export class NgIf { private _updateView() { ... if (this._thenTemplateRef) { this._thenViewRef = this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context); It's used to create a view using ComponentFactory. It's created by Angular compiler when you specify a component in the bootstrap property of the module and so the compiler generates a factory for it. The view created using this method is called a hostview.
import { Component, ViewContainerRef, ComponentFactoryResolver, NgZone, VERSION, ViewChild } from '@angular/core'; @Component({ selector: 'hello', template: `<h1>Hello Component!</h1>`, styles: [``] }) export class HelloComponent {} @Component({ selector: 'my-app', template: ` <ng-container #vc></ng-container> `, styles: [''] }) export class AppComponent { @ViewChild('vc', {read:ViewContainerRef}) vc: ViewContainerRef; constructor(private resolver: ComponentFactoryResolver) {} ngOnInit() { const factory = this.resolver.resolveComponentFactory(HelloComponent); this.vc.createComponent(factory); } } Stackblitz demo.
To learn more about the difference between a host view and an embedded view read What is the difference between a view, a host view and an embedded view
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With