Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between createEmbeddedView and createComponent?

Tags:

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".

like image 961
Blaze Avatar asked Sep 21 '17 08:09

Blaze


People also ask

What is the difference between ElementRef TemplateRef and ViewContainerRef?

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 .

What is createEmbeddedView Angular?

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 .

What is the difference between component view Host view and 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> ).

What is TemplateRef and ViewContainerRef in Angular?

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.


1 Answers

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.

createEmbeddedView

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); 

createComponent

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

like image 142
Max Koretskyi Avatar answered Sep 22 '22 09:09

Max Koretskyi