Angular 4.x NgIf usage, angularngif

Source: Internet
Author: User
Tags export class

Angular 4.x NgIf usage, angularngif

NgIf instructions

The ngIf command is used to render then or else template content at a specified position based on the expression value.

  1. The then template is an inline template associated with the ngIf command by default unless it is bound to different values.
  2. The else template is null by default unless it is bound with the corresponding value.

NgIf instruction syntax

Simple Form

<! -- Syntax sugar --> <div * ngIf = "condition">... </div> <! -- Use template in Angular 2.x --> <ng-template [ngIf] = "condition"> <div>... </div> </ng-template>

Use else Blocks

<div *ngIf="condition; else elseBlock">...</div><ng-template #elseBlock>...</ng-template>

Use then and else Blocks

<div *ngIf="condition; then thenBlock else elseBlock"></div><ng-template #thenBlock>...</ng-template><ng-template #elseBlock>...</ng-template>

Use the as syntax

<div *ngIf="condition as value; else elseBlock">{{value}}</div><ng-template #elseBlock>...</ng-template>

NgIf usage example

@Component({ selector: 'ng-if-then-else', template: `  <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>  <button (click)="switchPrimary()">Switch Primary</button>    show = {{show}}  <br>  <div *ngIf="show; then thenBlock; else elseBlock">this is ignored</div>  <ng-template #primaryBlock>Primary text to show</ng-template>  <ng-template #secondaryBlock>Secondary text to show</ng-template>  <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template> `})class NgIfThenElse implements OnInit { thenBlock: TemplateRef<any> = null; show: boolean = true;  @ViewChild('primaryBlock') primaryBlock: TemplateRef<any> = null; @ViewChild('secondaryBlock') secondaryBlock: TemplateRef<any> = null;  switchPrimary() {  this.thenBlock = this.thenBlock === this.primaryBlock ?    this.secondaryBlock : this.primaryBlock; }  ngOnInit() {    this.thenBlock = this.primaryBlock; }}

Basic knowledge

TemplateRef
The TemplateRef instance is used to represent the template object. The TemplateRef abstract class is defined as follows:

// angular\packages\core\src\linker\template_ref.tsexport abstract class TemplateRef<C> { abstract get elementRef(): ElementRef; abstract createEmbeddedView(context: C): EmbeddedViewRef<C>;}

ViewContainerRef

The ViewContainerRef instance provides createEmbeddedView() Method, which receivesTemplateRef The object is used as a parameter, and the content in the template is inserted into the page as the sibling element of the container (comment element.

NgIfContext

The NgIfContext instance is used to represent the NgIf context.

// angular\packages\common\src\directives\ng_if.tsexport class NgIfContext { public $implicit: any = null; public ngIf: any = null;}

NgIf source code analysis

NgIf instruction Definition

@ Directive ({selector: '[ngIf]' // attribute selector-<ng-template [ngIf] = "condition"> })

NgIf private attributes and constructor

Export class NgIf {// create NgIfContext context private _ context: NgIfContext = new NgIfContext (); // indicates the then template object private _ thenTemplateRef: TemplateRef <NgIfContext> | null = null; // indicates the else template object private _ elseTemplateRef: TemplateRef <NgIfContext> | null = null; // indicates the EmbeddedViewRef view private _ thenViewRef created based on the then template: optional <NgIfContext> | null = null; // indicates the EmbeddedViewRef view private _ elseViewRef: EmbeddedViewRef <NgIfContext> | null = null; constructor (private _ viewContainer: ViewContainerRef, templateRef: TemplateRef <NgIfContext>) {this. _ thenTemplateRef = templateRef; // The default value of the then template is the inline template associated with the ngIf instruction }}

NgIf input attributes

@ Input () set ngIf (condition: any) {this. _ context. $ implicit = this. _ context. ngIf = condition; this. _ updateView (); // update view} @ Input () set ngIfThen (templateRef: TemplateRef <NgIfContext>) {this. _ thenTemplateRef = templateRef; this. _ thenViewRef = null; // clear the previously created view this. _ updateView () ;}@ Input () set ngIfElse (templateRef: TemplateRef <NgIfContext>) {this. _ elseTemplateRef = templateRef; this. _ elseViewRef = null; // clear the previously created view this. _ updateView ();}

_ UpdateView () Private Method

// Update the private _ updateView () {// this. _ context. $ implicit = this. _ context. ngIf = condition // if the value of the condition expression is truthy if (this. _ context. $ implicit) {// if _ thenViewRef is null and _ thenTemplateRef exists, create the _ thenViewRef embedded view if (! This. _ thenViewRef) {this. _ viewContainer. clear (); this. _ elseViewRef = null; if (this. _ thenTemplateRef) {this. _ thenViewRef = this. _ viewContainer. createEmbeddedView (this. _ thenTemplateRef, this. _ context) ;}} else {// The condition expression value is falsy // if _ elseViewRef is null and _ elseTemplateRef exists, the _ elseViewRef embedded view if (! This. _ elseViewRef) {this. _ viewContainer. clear (); this. _ thenViewRef = null; if (this. _ elseTemplateRef) {this. _ elseViewRef = this. _ viewContainer. createEmbeddedView (this. _ elseTemplateRef, this. _ context );}}}}

ngIf The command source code is relatively simple, and the core is_updateView() Method. The most important function of this method is to create an embedded view based on the template object. Next, let's analyzeViewContainerRef Object createEmbeddedView() Method.

ViewContainerRef-createEmbeddedView ()

Method Signature

// Angular \ packages \ core \ src \ linker \ view_container_ref.tsexport abstract class ViewContainerRef {/*** create Embedded View (Embedded View) based on the TemplateRef object ), insert it to the container based on the value specified by 'index. * If the 'index' value is not specified, the newly created view is inserted as the last view in the container. */Abstract createEmbeddedView <C> (templateRef: TemplateRef <C>, context? : C, index? : Number): EmbeddedViewRef <C> ;}

Method implementation

// Angular \ packages \ core \ src \ view \ refs. tsclass ViewContainerRef _ implements ViewContainerData {//... createEmbeddedView <C> (templateRef: TemplateRef <C>, context? : C, index? : Number): EmbeddedViewRef <C >{// call the TemplateRef object createEmbeddedView () method to create the EmbeddedViewRef object const viewRef = templateRef. createEmbeddedView (context | <any >{}); // insert it to the view container Based on the specified index value. this. insert (viewRef, index); return viewRef ;}// the ViewContainerData interface inherits from the ViewContainerRef abstract class export interface ViewContainerData extends ViewContainerRef {_ embeddedViews: ViewData [];} export interface ViewData {def: viewDefinition; root: RootData; renderer: Renderer2; parentNodeDef: NodeDef | null; parent: ViewData | null; viewContainerParent: ViewData | null; component: any; context: any; nodes: {[key: number]: NodeData}; state: ViewState; oldValues: any []; disposables: DisposableFn [] | null ;}

ObserveViewContainerRef_ Class createEmbeddedView() Method, we find that this method is called internallyTemplateRef ObjectcreateEmbeddedView() To create an embedded view. So let's analyze it again.TemplateRefObjectcreateEmbeddedView() Method.

TemplateRef-createEmbeddedView ()

Method Signature

// angular\packages\core\src\linker\template_ref.tsexport abstract class TemplateRef<C> { abstract createEmbeddedView(context: C): EmbeddedViewRef<C>;}

Method implementation

// angular\packages\core\src\view\refs.tsclass TemplateRef_ extends TemplateRef<any> implements TemplateData { // ... createEmbeddedView(context: any): EmbeddedViewRef<any> {  return new ViewRef_(Services.createEmbeddedView(    this._parentView, this._def, this._def.element !.template !, context)); }}export interface TemplateData extends TemplateRef<any> { _projectedViews: ViewData[];}

After reading the source code above, there is no doubt that we will continue to analyze it.Services Object createEmbeddedView() Method.

Services-createEmbeddedView ()

Services object definition

// angular\packages\core\src\view\types.tsexport const Services: Services = { setCurrentNode: undefined !, createRootView: undefined !, createEmbeddedView: undefined !, createComponentView: undefined !, createNgModuleRef: undefined !, overrideProvider: undefined !, clearProviderOverrides: undefined !, checkAndUpdateView: undefined !, checkNoChangesView: undefined !, destroyView: undefined !, resolveDep: undefined !, createDebugContext: undefined !, handleEvent: undefined !, updateDirectives: undefined !, updateRenderer: undefined !, dirtyParentQueries: undefined !,};

Services object initialization

// angular\packages\core\src\view\services.tsexport function initServicesIfNeeded() { if (initialized) {  return; } initialized = true; const services = isDevMode() ? createDebugServices() : createProdServices(); Services.setCurrentNode = services.setCurrentNode; Services.createRootView = services.createRootView; Services.createEmbeddedView = services.createEmbeddedView; Services.createComponentView = services.createComponentView; Services.createNgModuleRef = services.createNgModuleRef; Services.overrideProvider = services.overrideProvider; Services.clearProviderOverrides = services.clearProviderOverrides; Services.checkAndUpdateView = services.checkAndUpdateView; Services.checkNoChangesView = services.checkNoChangesView; Services.destroyView = services.destroyView; Services.resolveDep = resolveDep; Services.createDebugContext = services.createDebugContext; Services.handleEvent = services.handleEvent; Services.updateDirectives = services.updateDirectives; Services.updateRenderer = services.updateRenderer; Services.dirtyParentQueries = dirtyParentQueries;}

IninitServicesIfNeeded()Method, different Services objects are created based on the current mode. Next let's take a look at it.createProdServices() Method:

Function createProdServices () {return {setCurrentNode: () =>{}, createRootView: createProdRootView, createEmbeddedView: createEmbeddedView // other methods are omitted}

CreateEmbeddedView () method

// Angular \ packages \ core \ src \ view. tsexport function createEmbeddedView (parent: ViewData, anchorDef: NodeDef, viewDef: ViewDefinition, context? : Any): ViewData {// embedded views are seen as siblings to the anchor, so we need // to get the parent of the anchor and use it as parentIndex. // create the ViewData object const view = createView (parent. root, parent. renderer, parent, anchorDef, viewDef); // initialize the ViewData object-set the value of component and context attributes initView (view, parent. component, context); // create a node in the view, that is, set view. value of the nodes array // const nodes = view. nodes; (...) {...; nodes [I] = nodeData;} createViewNodes (view); return view ;}

At this time, we find that if we analyze all the methods completely, it will involve too much content. Source code analysis ends here. If you are interested, please read the source code yourself (please forgive me ). Next, let's make a summary. createEmbeddedView() Method call process:

ViewContainerRef_ -> createEmbeddedView()  => TemplateRef_ -> createEmbeddedView()  => Services -> createEmbeddedView()   => Call createEmbeddedView()

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.