亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

Angular2學習教程之TemplateRef和ViewContainerRef詳解

2019-11-19 16:29:23
字體:
來源:轉載
供稿:網友

TemplateRef

在介紹 TemplateRef 前,我們先來了解一下 HTML 模板元素 - <template> 。模板元素是一種機制,允許包含加載頁面時不渲染,但又可以隨后通過 JavaScript 進行實例化的客戶端內容。我們可以將模板視作為存儲在頁面上稍后使用的一小段內容。

在 HTML5 標準引入 template 模板元素之前,我們都是使用 <script> 標簽進行客戶端模板的定義,具體如下:

<script id="tpl-mock" type="text/template"> <span>I am span in mock template</span></script>

對于支持 HTML5 template 模板元素的瀏覽器,我們可以這樣創建客戶端模板:

<template id="tpl"> <span>I am span in template</span></template>

下面我們來看一下 HTML5 template 模板元素的使用示例:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"> <title>HTML5 Template Element Demo</title></head><body><h4>HTML5 Template Element Demo</h4><!-- Template Container --><div class="tpl-container"></div><!-- Template --><template id="tpl"> <span>I am span in template</span></template><!-- Script --><script type="text/javascript"> (function renderTpl() { if ('content' in document.createElement('template')) { var tpl = document.querySelector('#tpl'); var tplContainer = document.querySelector('.tpl-container'); var tplNode = document.importNode(tpl.content, true); tplContainer.appendChild(tplNode);  } else { throw new Error("Current browser doesn't support template element"); } })();</script></body></html>

以上代碼運行后,在瀏覽器中我們會看到以下內容:

HTML5 Template Element DemoI am span in template

而當我們注釋掉 tplContainer.appendChild(tplNode) 語句時,刷新瀏覽器后看到的是:

HTML5 Template Element Demo

這說明頁面中 <template> 模板元素中的內容,如果沒有進行處理對用戶來說是不可見的。Angular 2 中,<template> 模板元素主要應用在結構指令中,接下來我們先來介紹一下本文中的第一個主角 - TemplateRef:

import {Component, TemplateRef, ViewChild, AfterViewInit} from '@angular/core';@Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <template #tpl> <span>I am span in template</span> </template> `,})export class AppComponent { name: string = 'Semlinker'; @ViewChild('tpl') tpl: TemplateRef<any>; ngAfterViewInit() { console.dir(this.tpl); }}

上述代碼運行后的控制臺的輸出結果如下:

從上圖中,我們發現 @Component template 中定義的 <template> 模板元素,渲染后被替換成 comment 元素,其內容為 "template bindings={}" 。此外我們通過 @ViewChild 獲取的模板元素,是 TemplateRef_ 類的實例,接下來我們來研究一下 TemplateRef_ 類:

TemplateRef_

// @angular/core/src/linker/template_ref.d.tsexport declare class TemplateRef_<C> extends TemplateRef<C> { private _parentView; private _nodeIndex; private _nativeElement; constructor(_parentView: AppView<any>, _nodeIndex: number, _nativeElement: any); createEmbeddedView(context: C): EmbeddedViewRef<C>; elementRef: ElementRef;}

TemplateRef

// @angular/core/src/linker/template_ref.d.ts// 用于表示內嵌的template模板,能夠用于創建內嵌視圖(Embedded Views)export declare abstract class TemplateRef<C> { elementRef: ElementRef; abstract createEmbeddedView(context: C): EmbeddedViewRef<C>;}

(備注:抽象類與普通類的區別是抽象類有包含抽象方法,不能直接實例化抽象類,只能實例化該抽象類的子類)

我們已經知道 <template> 模板元素,渲染后被替換成 comment 元素,那么應該如何顯示我們模板中定義的內容呢 ?我們注意到了 TemplateRef 抽象類中定義的 createEmbeddedView抽象方法,該方法的返回值是 EmbeddedViewRef 對象。那好我們馬上來試一下:

import {Component, TemplateRef, ViewChild, AfterViewInit} from '@angular/core';@Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <template #tpl> <span>I am span in template</span> </template> `,})export class AppComponent { name: string = 'Semlinker'; @ViewChild('tpl') tpl: TemplateRef<any>; ngAfterViewInit() { let embeddedView = this.tpl.createEmbeddedView(null); console.dir(embeddedView); }}

上述代碼運行后的控制臺的輸出結果如下:

從圖中我們可以知道,當調用 createEmbeddedView 方法后返回了 ViewRef_ 視圖對象。該視圖對象的 rootNodes 屬性包含了 <template> 模板中的內容。在上面的例子中,我們知道了 TemplateRef 實例對象中的 elementRef 屬性封裝了我們的 comment 元素,那么我們可以通過 insertBefore 方法來創建我們模板中定義的內容。

import { Component, TemplateRef, ViewChild, AfterViewInit } from '@angular/core';@Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <template #tpl> <span>I am span in template {{name}}</span> </template> `,})export class AppComponent { name: string = 'Semlinker'; @ViewChild('tpl') tpl: TemplateRef<any>; ngAfterViewInit() { // 頁面中的<!--template bindings={}-->元素 let commentElement = this.tpl.elementRef.nativeElement; // 創建內嵌視圖 let embeddedView = this.tpl.createEmbeddedView(null); // 動態添加子節點 embeddedView.rootNodes.forEach((node) => { commentElement.parentNode  .insertBefore(node, commentElement.nextSibling); }); }}

成功運行上面的代碼后,在瀏覽器中我們會看到以下內容:

Welcome to Angular WorldI am span in template

現在我們來回顧一下,上面的處理步驟:

  • 創建內嵌視圖(embedded view)
  • 遍歷內嵌視圖中的 rootNodes,動態的插入 node

雖然我們已經成功的顯示出 template 模板元素中的內容,但發現整個流程還是太復雜了,那有沒有簡單地方式呢 ?是時候介紹本文中第二個主角 - ViewContainerRef。

ViewContainerRef

我們先來檢驗一下它的能力,然后再來好好地分析它。具體示例如下:

import { Component, TemplateRef, ViewChild, ViewContainerRef, AfterViewInit } from '@angular/core';@Component({ selector: 'my-app', template: ` <h1>Welcome to Angular World</h1> <template #tpl>  <span>I am span in template</span> </template> `,})export class AppComponent { name: string = 'Semlinker'; @ViewChild('tpl') tplRef: TemplateRef<any>; @ViewChild('tpl', { read: ViewContainerRef }) tplVcRef: ViewContainerRef; ngAfterViewInit() { // console.dir(this.tplVcRef); (1) this.tplVcRef.createEmbeddedView(this.tplRef); }}

移除上面代碼中的注釋,即可在控制臺看到以下的輸出信息:

而在瀏覽器中我們會看到以下內容:

Welcome to Angular WorldI am span in template

接下來我們來看一下 ViewContainerRef_ 類:

// @angular/core/src/linker/view_container_ref.d.ts// 用于表示一個視圖容器,可添加一個或多個視圖export declare class ViewContainerRef_ implements ViewContainerRef { ... length: number; // 返回視圖容器中已存在的視圖個數 element: ElementRef; injector: Injector; parentInjector: Injector;  // 基于TemplateRef創建內嵌視圖,并自動添加到視圖容器中,可通過index設置 // 視圖添加的位置 createEmbeddedView<C>(templateRef: TemplateRef<C>, context?: C,   index?: number): EmbeddedViewRef<C>; // 基 ComponentFactory創建組件視圖 createComponent<C>(componentFactory: ComponentFactory<C>,  index?: number, injector?: Injector, projectableNodes?: any[][]): ComponentRef<C>; insert(viewRef: ViewRef, index?: number): ViewRef; move(viewRef: ViewRef, currentIndex: number): ViewRef; indexOf(viewRef: ViewRef): number; remove(index?: number): void; detach(index?: number): ViewRef; clear(): void;}

通過源碼我們可以知道通過 ViewContainerRef_ 實例,我們可以方便地操作視圖,也可以方便地基于 TemplateRef 創建視圖。現在我們來總結一下 TemplateRef 與 ViewContainerRef。

TemplateRef:用于表示內嵌的 template 模板元素,通過 TemplateRef 實例,我們可以方便創建內嵌視圖(Embedded Views),且可以輕松地訪問到通過 ElementRef 封裝后的 nativeElement。需要注意的是組件視圖中的 template 模板元素,經過渲染后會被替換成 comment 元素。

ViewContainerRef:用于表示一個視圖容器,可添加一個或多個視圖。通過 ViewContainerRef 實例,我們可以基于 TemplateRef 實例創建內嵌視圖,并能指定內嵌視圖的插入位置,也可以方便對視圖容器中已有的視圖進行管理。簡而言之,ViewContainerRef 的主要作用是創建和管理內嵌視圖或組件視圖。

我有話說

1.Angular 2 支持的 View(視圖) 類型有哪幾種 ?

  • Embedded Views - Template 模板元素
  • Host Views - Component 組件

1.1 如何創建 Embedded View

ngAfterViewInit() { let view = this.tpl.createEmbeddedView(null);}

1.2 如何創建 Host View

constructor(private injector: Injector, private r: ComponentFactoryResolver) { let factory = this.r.resolveComponentFactory(AppComponent); let componentRef = factory.create(injector); let view = componentRef.hostView;}

2.Angular 2 Component 組件中定義的 <template> 模板元素為什么渲染后會被移除 ?

因為 <template> 模板元素,已經被 Angular 2 解析并封裝成 TemplateRef 實例,通過 TemplateRef 實例,我們可以方便地創建內嵌視圖(Embedded View),我們不需要像開篇中的例子那樣,手動操作 <template> 模板元素。

3.ViewRef 與 EmbeddedViewRef 之間有什么關系 ?

ViewRef 用于表示 Angular View(視圖),視圖是可視化的 UI 界面。EmbeddedViewRef 繼承于 ViewRef,用于表示 <template> 模板元素中定義的 UI 元素。

ViewRef

// @angular/core/src/linker/view_ref.d.tsexport declare abstract class ViewRef { destroyed: boolean; abstract onDestroy(callback: Function): any;}

EmbeddedViewRef

// @angular/core/src/linker/view_ref.d.tsexport declare abstract class EmbeddedViewRef<C> extends ViewRef { context: C; rootNodes: any[]; // 保存<template>模板中定義的元素 abstract destroy(): void; // 用于銷毀視圖}

總結

Angular 2 中 TemplateRef 與 ViewContainerRef 的概念對于初學者來說會比較羞澀難懂,本文從基本的 HTML 5 <template> 模板元素開始,介紹了如何操作和應用頁面中定義的模板。然后通過實例介紹了 Angular 2 中 TemplateRef 和 ViewContainerRef 的定義和作用。希望通過這篇文章,讀者能更好的理解 TemplateRef 與 ViewContainerRef。

好了,以上就是這篇文章的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美一级视频在线观看| 欧美日韩在线一区| 亚洲欧洲一区二区三区在线观看| 国产精品99一区| 久久久91精品| 日韩视频中文字幕| 日本国产一区二区三区| 综合网中文字幕| 清纯唯美亚洲综合| 国产综合福利在线| 国产精品视频白浆免费视频| 亚洲香蕉伊综合在人在线视看| 欧美激情视频网| 午夜精品一区二区三区在线播放| 国产一区二区丝袜| 国产精品视频网站| 91国产视频在线| 欧美黑人性视频| 91沈先生在线观看| 国产精品美女午夜av| 欧美日韩在线观看视频小说| 伊人一区二区三区久久精品| 亚洲第一福利在线观看| 亚洲sss综合天堂久久| 中文字幕在线国产精品| 九九久久国产精品| 久久久天堂国产精品女人| 91亚洲精品一区| 国产一区二区丝袜| 国产成人中文字幕| 91欧美精品午夜性色福利在线| 91po在线观看91精品国产性色| 96精品视频在线| 成人欧美在线观看| 日韩免费视频在线观看| 国产日韩换脸av一区在线观看| 亚洲色图日韩av| 尤物yw午夜国产精品视频明星| 欧美综合国产精品久久丁香| 日韩成人小视频| 日韩美女在线观看一区| 日韩av在线免费观看一区| 欧美高清视频一区二区| 国产在线拍揄自揄视频不卡99| 日韩动漫免费观看电视剧高清| 亚洲午夜色婷婷在线| 亚洲精品日韩av| 国精产品一区一区三区有限在线| 国产精品免费一区二区三区都可以| 国产一区二区激情| 欧美日韩中文字幕在线| 久久中文字幕视频| 国产精品九九九| 久久综合国产精品台湾中文娱乐网| 91精品国产高清久久久久久91| 国产精品无av码在线观看| 亚洲成人国产精品| 久久亚洲精品中文字幕冲田杏梨| 国产成人福利夜色影视| 国产精品福利久久久| 日韩av中文字幕在线免费观看| 成人黄色在线播放| 国内外成人免费激情在线视频| 国产精品亚洲片夜色在线| 国产精品成人aaaaa网站| 日韩电影中文字幕在线观看| 国产精品视频色| 欧美一区二区影院| 中文字幕日韩欧美在线| 亚洲精品国产精品国产自| 一个人www欧美| 久久乐国产精品| 91在线免费观看网站| 裸体女人亚洲精品一区| 国产精品网红直播| 中文字幕亚洲欧美| 亚洲精品动漫100p| zzjj国产精品一区二区| 日本精品免费一区二区三区| 日韩精品在线视频观看| 性欧美亚洲xxxx乳在线观看| 亚洲性线免费观看视频成熟| 久久久久久久久91| 日韩欧美黄色动漫| 欧美色播在线播放| 亚洲天堂av网| 国产精品视频男人的天堂| 超薄丝袜一区二区| 国产高清视频一区三区| 韩国三级日本三级少妇99| 91情侣偷在线精品国产| 国产精品毛片a∨一区二区三区|国| 黄色成人在线免费| 国产精品美女免费视频| 亚洲精品欧美日韩| 国产一区欧美二区三区| 久久亚洲一区二区三区四区五区高| xxxx欧美18另类的高清| 午夜精品一区二区三区视频免费看| 国产网站欧美日韩免费精品在线观看| 亚洲男人天堂网站| 亚洲精品suv精品一区二区| 久久精品影视伊人网| 亚洲成人精品久久久| x99av成人免费| 日韩一区av在线| 久久免费国产视频| 亚洲视频在线观看免费| 中文在线不卡视频| 欧美做受高潮电影o| 精品久久久香蕉免费精品视频| 成人国产亚洲精品a区天堂华泰| 久久久久久久久网站| 国产一区二区黑人欧美xxxx| 欧美激情一区二区三区在线视频观看| 一区二区三区无码高清视频| 国产精品成人观看视频国产奇米| 国产欧美日韩综合精品| 欧美一区二三区| 亚洲天堂av在线免费观看| 中文字幕欧美日韩va免费视频| 亚洲性线免费观看视频成熟| 国产精品一区专区欧美日韩| 国产精品久久久久7777婷婷| 91成品人片a无限观看| 亚洲图片欧洲图片av| 欧美极品少妇xxxxⅹ裸体艺术| 亚洲精品中文字幕av| 亚洲国产私拍精品国模在线观看| 亚洲一区999| 欧美精品一二区| 国外日韩电影在线观看| 国产精品1区2区在线观看| 国产91精品久久久| 欧美日韩激情视频8区| 亚洲欧洲在线免费| 91香蕉嫩草影院入口| 精品亚洲夜色av98在线观看| 51ⅴ精品国产91久久久久久| 成人精品在线观看| 国产精品久久久久久久久久久久久久| 久久夜精品va视频免费观看| 中文字幕亚洲无线码a| 欧美性xxxx极品高清hd直播| 日韩女优在线播放| 国产精品亚洲第一区| 在线免费看av不卡| 国产精品一区二区久久久| 97香蕉久久超级碰碰高清版| 综合136福利视频在线| 欧美精品激情视频| 日韩在线视频线视频免费网站| 欧美日韩一区二区在线播放| 日韩电影免费在线观看中文字幕| 亚洲另类图片色| 欧美日韩xxx| 精品免费在线观看| 国产自摸综合网| 久久久成人精品视频| 日韩最新免费不卡| 91在线视频成人| 68精品久久久久久欧美| 久久综合伊人77777尤物| 国产成人欧美在线观看|