Pawel Kozlowski - Reactive parenting with Angular 2 - NG-BE 2016

By: NG - BE

53   0   2584

Uploaded on 12/21/2016

If concepts like View, ViewContainer, TemplateRef or HostView get your head spinning - fear no more! During this talk I'm going to demystify Angular 2 rendering layer. Spend 30 minutes with me to learn how to handle complex rendering scenarios like a pro!

Comments (4):

By anonymous    2017-09-20

ViewContainerRef just point to element that will be host for inserting views. Those views will be added as siblings to this host element.

For structural directive comment like <!----> will be host element.

Desugar for

<div *appDelay="500">
    Hooray
</div>

will be

<ng-template [appDelay]="500">
    <div>
        Hooray
    </div>
</ng-template>

it also can be described like so:

<ng-template view-container-ref></ng-template>
<!-- ViewRef -->
  <div>
    Hooray
  </div>
<!-- /ViewRef -->

Since ng-template is not stamped to the DOM it will be rendered as <!---->.

Angular will create ViewContainerRef with reference to this comment tag.

vcRef.element.nativeElement

Each ViewContainer can have only one anchor element and each anchor element can only have a single ViewContainer. ViewContainer is a container that helps you to manipulate Views(ViewRef, EmbeddedViewRef)

Also TemplateRef instance will be created

class TemplateRef_ {
  constructor(private _parentView: ViewData, private _def: NodeDef) { }

  get elementRef(): ElementRef {
    return new ElementRef(asElementData(this._parentView, this._def.index).renderElement);
  }

and its elementRef(anchor or location) will point to the same comment element.

The main feature of TemplateRef is having template property

this.templateRef._def.element.template

This property doesn't contains html string but describes view

this.templateRef._def.element.template.factory + ''

will print

"function View_AppComponent_1(_l) {
  return jit_viewDef1(0,[(_l()(),jit_elementDef2(0,null,null,1,'div',[],null,null,
      null,null,null)),(_l()(),jit_textDef3(null,['\n    Hooray\n']))],null,null);
}"

so this is our template. As you can see it describes view with div root element and child text node with text \n Hooray\n

Angular uses such ViewDefinitions which are located in ngfactories to build the DOM treeenter image description here

See also

Don't forget to watch https://www.youtube.com/watch?v=EMjTp12VbQ8

Original Thread

By anonymous    2017-09-20

There is projectableNodes parameter for vcRef.createComponent method

createComponent<C>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][], ngModule?: NgModuleRef<any>): ComponentRef<C>;

You can use it to dynamically inject one component in another.

Let say we have the following component

@Component({
    selector: 'card',
    template: `
        <div class="card__top">
            <h2>Creating a angular2 component with ng-content dynamically</h2>
        </div>
        <div class="card__body">
            <ng-content></ng-content>
        </div>
        <div class="card__bottom">
            <ng-content></ng-content>
        </div>
    `
})
export class CardComponent {}

We want to create it dynamically and insert some controls to its ng-content locations. It could be done like follows:

const bodyFactory = this.cfr.resolveComponentFactory(CardBodyComponent);
const footerFactory = this.cfr.resolveComponentFactory(CardFooterComponent);

let bodyRef = this.vcRef.createComponent(bodyFactory);
let footerRef = this.vcRef.createComponent(footerFactory);

const cardFactory = this.cfr.resolveComponentFactory(CardComponent);

const cardRef = this.vcRef.createComponent(
    cardFactory,
    0,
    undefined,
    [
        [bodyRef.location.nativeElement],
        [footerRef.location.nativeElement]
    ]
);

Plunker Example

See also

Original Thread

Recommended Books

    Submit Your Video

    If you have some great dev videos to share, please fill out this form.