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".
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".
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);
}
}
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);
}
}
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