最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

angular之ng-template模板加載

 更新時間:2017年11月09日 17:18:14   作者:OnePiece索隆  
本篇文章主要介紹了angular之ng-template模板加載,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本文介紹了angular之ng-template模板加載,分享給大家,具體如下:

html5中的template

template標簽的含義:HTML <template>元素是一種用于保存客戶端內容的機制,該內容在頁面加載時是不可見的,但可以在運行時使用JavaScript進行實例化,可以將一個模板視為正在被存儲以供隨后在文檔中使用的一個內容片段。

屬性

此元素僅包含全局屬性和只讀的 content 屬性,通過content 可以讀取模板內容,而且可以通過判斷 content 屬性是否存在來判斷瀏覽器是否支持 <template> 元素。

示例

html

<table id="producttable">
 <thead>
  <tr>
   <td>UPC_Code</td>
   <td>Product_Name</td>
  </tr>
 </thead>
 <tbody>
  <!-- 現(xiàn)有數據可以可選地包括在這里 -->
 </tbody>
</table>

<template id="productrow">
 <tr>
  <td class="record"></td>
  <td></td>
 </tr>
</template>

js

// 通過檢查來測試瀏覽器是否支持HTML模板元素 
// 用于保存模板元素的內容屬性。
if ('content' in document.createElement('template')) {

 // 使用現(xiàn)有的HTML tbody實例化表和該行與模板
 let t = document.querySelector('#productrow'),
 td = t.content.querySelectorAll("td");
 td[0].textContent = "1235646565";
 td[1].textContent = "Stuff";

 // 克隆新行并將其插入表中
 let tb = document.getElementsByTagName("tbody");
 let clone = document.importNode(t.content, true);
 tb[0].appendChild(clone);
 
 // 創(chuàng)建一個新行
 td[0].textContent = "0384928528";
 td[1].textContent = "Acme Kidney Beans";

 // 克隆新行并將其插入表中
 let clone2 = document.importNode(t.content, true);
 tb[0].appendChild(clone2);

} else {
 // 找到另一種方法來添加行到表,因為不支持HTML模板元素。
}

代碼運行后,結果將是一個包含(由 JavaScript 生成)兩個新行的 HTML 表格:

UPC_Code  Product_Name
1235646565 Stuff
0384928528 Acme Kidney Beans

注釋掉 tb[0].appendChild(clone);和tb[0].appendChild(clone2);,運行代碼,只會看到:
UPC_Code Product_Name

說明template元素中的內容如果不經過處理,瀏覽器是不會渲染的。

angular中的ng-template

<ng-template>是一個 Angular 元素,它永遠不會直接顯示出來。在渲染視圖之前,Angular 會把<ng-template>及其內容替換為一個注釋。

以ngIf為例:

<ng-template> 模板元素與html5的template元素一樣,需要被特殊處理后才能渲染。ng主要是通過類TemplateRef和ViewContainerRef實現(xiàn)的。

通過閱讀ngIf源碼學習如何運用<ng-template>

在使用ngIf 指令時我們并未發(fā)現(xiàn)ng-template的身影,這是因為"*"(星號)語法糖的原因,這個簡寫方法是一個微語法,而不是通常的模板表達式, Angular會解開這個語法糖,變成一個<ng-template>標記,包裹著宿主元素及其子元素。

<div *ngIf="hero" >{{hero.name}}</div>

會被解析為

<ng-template [ngIf]="hero">
 <div>{{hero.name}}</div>
</ng-template>`

看下ngIf源碼

import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '@angular/core';
@Directive({selector: '[ngIf]'})
export class NgIf {
 private _context: NgIfContext = new NgIfContext();
 private _thenTemplateRef: TemplateRef<NgIfContext>|null = null;
 private _elseTemplateRef: TemplateRef<NgIfContext>|null = null;
 private _thenViewRef: EmbeddedViewRef<NgIfContext>|null = null;
 private _elseViewRef: EmbeddedViewRef<NgIfContext>|null = null;

 constructor(private _viewContainer: ViewContainerRef, templateRef: TemplateRef<NgIfContext>) {
  this._thenTemplateRef = templateRef;
 }

 @Input()
 set ngIf(condition: any) {
  this._context.$implicit = this._context.ngIf = condition;
  this._updateView();
 }

 @Input()
 set ngIfThen(templateRef: TemplateRef<NgIfContext>) {
  this._thenTemplateRef = templateRef;
  this._thenViewRef = null; // clear previous view if any.
  this._updateView();
 }

 @Input()
 set ngIfElse(templateRef: TemplateRef<NgIfContext>) {
  this._elseTemplateRef = templateRef;
  this._elseViewRef = null; // clear previous view if any.
  this._updateView();
 }

 private _updateView() {
  if (this._context.$implicit) {
   if (!this._thenViewRef) {
    this._viewContainer.clear();
    this._elseViewRef = null;
    if (this._thenTemplateRef) {
     this._thenViewRef =
       this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
    }
   }
  } else {
   if (!this._elseViewRef) {
    this._viewContainer.clear();
    this._thenViewRef = null;
    if (this._elseTemplateRef) {
     this._elseViewRef =
       this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
    }
   }
  }
 }
}

export class NgIfContext {
 public $implicit: any = null;
 public ngIf: any = null;
}

ngIf的源碼并不難,它的核心就在于_updateView函數,它主要通過ViewContainerRef的createEmbeddedView和clear方法來實現(xiàn)模板TemplateRef的呈現(xiàn)和清除(先不關注當中的then和else等的具體實現(xiàn))。它使用TemplateRef取得<ng-template>的內容,并通過ViewContainerRef來訪問這個視圖容器。

TemplateRef

TemplateRef 實例用于表示模板對象,TemplateRef 抽象類的定義如下:

 abstract get elementRef(): ElementRef;
 abstract createEmbeddedView(context: C): EmbeddedViewRef<C>;
}

在指令中通過依賴注入TemplateRef可以直接拿到ng-tempalte的TemplateRef,但是在component組件中我們則需要使用viewChild

<ng-template #tptest>
 <span>template test</span>
</ng-template>

@ViewChild('tptest') tptest: TemplateRef<any>;

ViewContainerRef

ViewContainerRef 實例提供了 createEmbeddedView() 方法,該方法接收 TemplateRef 對象作為參數,并將模板中的內容作為容器 (comment 元素) 的兄弟元素,插入到頁面中。

export abstract class ViewContainerRef {
  /*基于TemplateRef對象創(chuàng)建Embedded View(內嵌視圖),然后根據`index`指定的值,插入到容器中。 
  如果沒有指定`index`的值,新創(chuàng)建的視圖將作為容器中的最后一個視圖插入。*/ 
 abstract createEmbeddedView<C>(
   templateRef: TemplateRef<C>, //內嵌視圖
   context?: C, index?: number): // 創(chuàng)建上下文
   EmbeddedViewRef<C>;
}

createEmbeddedView:context

創(chuàng)建Template 自身 Context 的屬性,以ngFor為例:
查看ngFor Context源碼:

export class NgForOfContext<T> {
 constructor(
   public $implicit: T, public ngForOf: NgIterable<T>, public index: number,
   public count: number) {}

 get first(): boolean { return this.index === 0; }

 get last(): boolean { return this.index === this.count - 1; }

 get even(): boolean { return this.index % 2 === 0; }

 get odd(): boolean { return !this.even; }
}

<div *ngFor="let hero of heroes; let i=index; let odd=odd">
 ({{i}}) {{hero.name}}
</div>


解析后:

<ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" >
 <div>({{i}}) {{hero.name}}</div>
</ng-template>

從例子中可以看到,通過let-i let-odd可以獲取到Template的context,這是angular提供的一種語法。因為在 Angular中是沒有作用域繼承的,所以在模版中無法隱式實現(xiàn)兩個無關數據源。一個簡單的實現(xiàn)方案就是:一個顯式、一個隱式。由于ng-template tag 是寫在某個 Component 的 template屬性中的,所以在 ng-template tag 之下的部分當然能訪問的也只有 Component 作為 Context 提供的屬性,從而保持行為的一致性,而如果需要訪問到 Template 的 Context,我們就需要使用額外的引入語法。比如 let-i="index",就是把 Template Context 中的 index屬性引入到當前的 Component Context 中并賦予別名 i,這樣,我們就能夠使用 i 這個標識符來訪問到 Template Context 中的屬性了,并且仍然保持了行為的一致性和作用域的獨立性。

模板輸入變量是這樣一種變量,你可以在單個實例的模板中引用它的值。 這個例子中有好幾個模板輸入變量:hero、i和odd。 它們都是用let作為前導關鍵字。

模板輸入變量和模板引用變量是不同的,無論是在語義上還是語法上。

我們使用let關鍵字(如let hero)在模板中聲明一個模板輸入變量。 這個變量的范圍被限制在所重復模板的單一實例上。
而聲明模板引用變量使用的是給變量名加#前綴的方式(#var)。 一個引用變量引用的是它所附著到的元素、組件或指令。它可以在整個模板任意位置**訪問。

模板輸入變量和引用變量具有各自獨立的命名空間。let hero中的hero和#hero中的hero并不是同一個變量。

總結:

<ng-template>在ng中主要通過viewChild TemplateRef ViewContainerRef來實現(xiàn)結構性操作。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • JavaScript代碼異常監(jiān)控實現(xiàn)過程詳解

    JavaScript代碼異常監(jiān)控實現(xiàn)過程詳解

    這篇文章主要介紹了JavaScript代碼異常監(jiān)控實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • 原生JavaScript實現(xiàn)幻燈片效果

    原生JavaScript實現(xiàn)幻燈片效果

    這篇文章主要為大家詳細介紹了原生JavaScript實現(xiàn)幻燈片效果,文中安裝步驟介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • 解決input輸入框僅支持輸入數字及兩位小數點的限制

    解決input輸入框僅支持輸入數字及兩位小數點的限制

    這篇文章主要為大家介紹了解決input輸入框僅支持輸入數字及兩位小數點的限制技巧示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • 詳解BootStrap中Affix控件的使用及保持布局的美觀的方法

    詳解BootStrap中Affix控件的使用及保持布局的美觀的方法

    Affix是BootStrap中的一個很有用的控件,他能夠監(jiān)視瀏覽器的滾動條的位置并讓你的導航始終都在頁面的可視區(qū)域。本文重點給大家介紹BootStrap中Affix控件的使用及保持布局的美觀的方法,感興趣的朋友一起看看吧
    2016-07-07
  • 跟我學習javascript的閉包

    跟我學習javascript的閉包

    跟我學習javascript的閉包,這篇文章的目的就是讓大家對javascript閉包有一個非常全面的了解,感興趣的小伙伴們可以參考一下。
    2015-11-11
  • weex slider實現(xiàn)滑動底部導航功能

    weex slider實現(xiàn)滑動底部導航功能

    這篇文章主要為大家詳細介紹了weex slider實現(xiàn)滑動底部導航功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • JavaScript常用代碼書寫規(guī)范的超全面總結

    JavaScript常用代碼書寫規(guī)范的超全面總結

    這篇文章給大家全面總結了JavaScript常用代碼的書寫規(guī)范,分別利用推薦和不推薦的兩種示例代碼讓大家更能直接的了解書寫規(guī)范,其實關于javascript代碼規(guī)范我們應該遵循古老的原則:“能做并不意味著應該做”,好了,下面我們就來一起看看吧。
    2016-09-09
  • style-loader為什么要使用pitch方法原理解析

    style-loader為什么要使用pitch方法原理解析

    這篇文章主要為大家介紹了style-loader為什么要使用pitch方法原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • JavaScript獲取服務器端時間的方法

    JavaScript獲取服務器端時間的方法

    這篇文章主要介紹了JavaScript獲取服務器端時間的方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-11-11
  • 詳解JS變量存儲深拷貝和淺拷貝

    詳解JS變量存儲深拷貝和淺拷貝

    這篇文章主要介紹了JS變量存儲深拷貝和淺拷貝,想深入了解JS的同學,可以參考下
    2021-05-05

最新評論

津市市| 石台县| 莱州市| 永安市| 德安县| 汉寿县| 仁布县| 迁西县| 扶余县| 南康市| 荔波县| 友谊县| 霍州市| 枣庄市| 巴南区| 彩票| 广水市| 海淀区| 故城县| 文昌市| 青田县| 察隅县| 玉树县| 青冈县| 怀仁县| 彭阳县| 灵武市| 区。| 隆林| 郓城县| 万载县| 西乌珠穆沁旗| 德江县| 浮山县| 宜川县| 佛冈县| 额敏县| 石渠县| 南通市| 岐山县| 崇义县|