欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

angular之ng-template模板加載

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

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

html5中的template

template標(biāo)簽的含義:HTML <template>元素是一種用于保存客戶端內(nèi)容的機(jī)制,該內(nèi)容在頁(yè)面加載時(shí)是不可見(jiàn)的,但可以在運(yùn)行時(shí)使用JavaScript進(jìn)行實(shí)例化,可以將一個(gè)模板視為正在被存儲(chǔ)以供隨后在文檔中使用的一個(gè)內(nèi)容片段。

屬性

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

示例

html

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

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

js

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

 // 使用現(xiàn)有的HTML tbody實(shí)例化表和該行與模板
 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)建一個(gè)新行
 td[0].textContent = "0384928528";
 td[1].textContent = "Acme Kidney Beans";

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

} else {
 // 找到另一種方法來(lái)添加行到表,因?yàn)椴恢С諬TML模板元素。
}

代碼運(yùn)行后,結(jié)果將是一個(gè)包含(由 JavaScript 生成)兩個(gè)新行的 HTML 表格:

UPC_Code  Product_Name
1235646565 Stuff
0384928528 Acme Kidney Beans

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

說(shuō)明template元素中的內(nèi)容如果不經(jīng)過(guò)處理,瀏覽器是不會(huì)渲染的。

angular中的ng-template

<ng-template>是一個(gè) Angular 元素,它永遠(yuǎn)不會(huì)直接顯示出來(lái)。在渲染視圖之前,Angular 會(huì)把<ng-template>及其內(nèi)容替換為一個(gè)注釋。

以ngIf為例:

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

通過(guò)閱讀ngIf源碼學(xué)習(xí)如何運(yùn)用<ng-template>

在使用ngIf 指令時(shí)我們并未發(fā)現(xiàn)ng-template的身影,這是因?yàn)?*"(星號(hào))語(yǔ)法糖的原因,這個(gè)簡(jiǎn)寫(xiě)方法是一個(gè)微語(yǔ)法,而不是通常的模板表達(dá)式, Angular會(huì)解開(kāi)這個(gè)語(yǔ)法糖,變成一個(gè)<ng-template>標(biāo)記,包裹著宿主元素及其子元素。

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

會(huì)被解析為

<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函數(shù),它主要通過(guò)ViewContainerRef的createEmbeddedView和clear方法來(lái)實(shí)現(xiàn)模板TemplateRef的呈現(xiàn)和清除(先不關(guān)注當(dāng)中的then和else等的具體實(shí)現(xiàn))。它使用TemplateRef取得<ng-template>的內(nèi)容,并通過(guò)ViewContainerRef來(lái)訪問(wèn)這個(gè)視圖容器。

TemplateRef

TemplateRef 實(shí)例用于表示模板對(duì)象,TemplateRef 抽象類(lèi)的定義如下:

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

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

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

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

ViewContainerRef

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

export abstract class ViewContainerRef {
  /*基于TemplateRef對(duì)象創(chuàng)建Embedded View(內(nèi)嵌視圖),然后根據(jù)`index`指定的值,插入到容器中。 
  如果沒(méi)有指定`index`的值,新創(chuàng)建的視圖將作為容器中的最后一個(gè)視圖插入。*/ 
 abstract createEmbeddedView<C>(
   templateRef: TemplateRef<C>, //內(nèi)嵌視圖
   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>

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

模板輸入變量是這樣一種變量,你可以在單個(gè)實(shí)例的模板中引用它的值。 這個(gè)例子中有好幾個(gè)模板輸入變量:hero、i和odd。 它們都是用let作為前導(dǎo)關(guān)鍵字。

模板輸入變量和模板引用變量是不同的,無(wú)論是在語(yǔ)義上還是語(yǔ)法上。

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

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

總結(jié):

<ng-template>在ng中主要通過(guò)viewChild TemplateRef ViewContainerRef來(lái)實(shí)現(xiàn)結(jié)構(gòu)性操作。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 利用JS實(shí)現(xiàn)scroll自定義滾動(dòng)效果詳解

    利用JS實(shí)現(xiàn)scroll自定義滾動(dòng)效果詳解

    這篇文章主要給大家介紹了關(guān)于利用JS如何實(shí)現(xiàn)scroll自定義滾動(dòng)效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • 基于JavaScript實(shí)現(xiàn)前端文件的斷點(diǎn)續(xù)傳

    基于JavaScript實(shí)現(xiàn)前端文件的斷點(diǎn)續(xù)傳

    這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)前端文件的斷點(diǎn)續(xù)傳的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • 談?wù)凧avaScript異步函數(shù)發(fā)展歷程

    談?wù)凧avaScript異步函數(shù)發(fā)展歷程

    對(duì)大部分JavaScript開(kāi)發(fā)者而言,async函數(shù)仍是新鮮事物,其發(fā)展經(jīng)歷了漫長(zhǎng)的旅程。本文將梳理總結(jié)JavaScript異步函數(shù)的發(fā)展歷程,并表示未來(lái)async函數(shù)將成為實(shí)現(xiàn)異步的主要方式。
    2015-09-09
  • 詳細(xì)談?wù)凧avaScript中循環(huán)之間的差異

    詳細(xì)談?wù)凧avaScript中循環(huán)之間的差異

    JS循環(huán)語(yǔ)句也叫迭代語(yǔ)句,是一種特殊的語(yǔ)句,主要用于需要多次執(zhí)行的代碼塊,下面這篇文章主要給大家介紹了關(guān)于JavaScript中循環(huán)之間的差異的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • JavaScript 學(xué)習(xí)筆記(七)字符串的連接

    JavaScript 學(xué)習(xí)筆記(七)字符串的連接

    javascript 字符串的連接效率問(wèn)題,需要的朋友可以參考下。
    2009-12-12
  • 原生js實(shí)現(xiàn)jquery函數(shù)animate()動(dòng)畫(huà)效果的簡(jiǎn)單實(shí)例

    原生js實(shí)現(xiàn)jquery函數(shù)animate()動(dòng)畫(huà)效果的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇原生js實(shí)現(xiàn)jquery函數(shù)animate()動(dòng)畫(huà)效果的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08
  • 用javascript實(shí)現(xiàn)自定義標(biāo)簽

    用javascript實(shí)現(xiàn)自定義標(biāo)簽

    用javascript實(shí)現(xiàn)自定義標(biāo)簽...
    2007-05-05
  • javascript消除window.close()的提示窗口

    javascript消除window.close()的提示窗口

    有人問(wèn)起,怎么去掉js調(diào)用window.close()時(shí)怎么去掉那可惡的提示,咋一看好像還真不好弄,IE的安全機(jī)制好像就不允許通過(guò)腳本關(guān)閉本頁(yè)面,但是IE好像可以允許js關(guān)閉彈出窗口,那我們是不是可以通過(guò)一定的技巧欺騙一下IE,繞過(guò)去呢。鼓搗了幾下,似乎還真可以做到
    2015-05-05
  • 微信小程序阻止頁(yè)面返回實(shí)例詳解(包滑動(dòng)、自動(dòng)返回鍵)

    微信小程序阻止頁(yè)面返回實(shí)例詳解(包滑動(dòng)、自動(dòng)返回鍵)

    小程序如果在頁(yè)面內(nèi)進(jìn)行復(fù)雜的界面設(shè)計(jì),用戶進(jìn)行返回操作會(huì)直接離開(kāi)當(dāng)前頁(yè)面,不符合用戶預(yù)期,下面這篇文章主要給大家介紹了關(guān)于微信小程序阻止頁(yè)面返回(包滑動(dòng)、自動(dòng)返回鍵)的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • 基于小程序請(qǐng)求接口wx.request封裝的類(lèi)axios請(qǐng)求

    基于小程序請(qǐng)求接口wx.request封裝的類(lèi)axios請(qǐng)求

    這篇文章主要介紹了基于小程序請(qǐng)求接口wx.request封裝的類(lèi)axios請(qǐng)求,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論