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

首頁 > 編程 > JavaScript > 正文

淺談angular4 ng-content 中隱藏的內容

2019-11-19 15:44:34
字體:
來源:轉載
供稿:網友

如果你嘗試在 Angular 中編寫可重復使用的組件,則可能會接觸到內容投射的概念。然后你發現了 <ng-content> ,并找到了一些關于它的文章,進而實現了所需的功能。

接下來我們來通過一個簡單的示例,一步步介紹 <ng-content> 所涉及的內容。

Simple example

在本文中我們使用一個示例,來演示不同的方式實現內容投影。由于許多問題與Angular 中的組件生命周期相關,因此我們的主要組件將顯示一個計數器,用于展示它已被實例化的次數:

import { Component } from '@angular/core';let instances = 0;@Component({ selector: 'counter', template: '<h1>{{this.id}}</h1>'})class Counter { id: number;  constructor() {  this.id = ++instances; }}

上面示例中我們定義了 Counter 組件,組件類中的 id 屬性用于顯示本組件被實例化的次數。接著我們繼續定義一個 Wrapper 組件:

import { Component } from '@angular/core';@Component({ selector: 'wrapper', template: `  <div class="box">   <ng-content></ng-content>  </div> `})class Wrapper {}

現在我們來驗證一下效果:

<wrapper> <counter></counter> <counter></counter> <counter></counter></wrapper>

Targeted projection

有時你希望將包裝器的不同子項投影到模板的不同部分。為了處理這個問題, <ng-content> 支持一個 select 屬性,可以讓你在特定的地方投射具體的內容。該屬性支持 CSS 選擇器(my-element,.my-class,[my-attribute],...)來匹配你想要的內容。如果 ng-content 上沒有設置 select 屬性,它將接收全部內容,或接收不匹配任何其他 ng-content 元素的內容。長話短說:

import { Component } from '@angular/core';@Component({ selector: 'wrapper', template: ` <div class="box red">  <ng-content></ng-content> </div> <div class="box blue">  <ng-content select="counter"></ng-content> </div> `, styles: [`  .red {background: red;}  .blue {background: blue;} `]})export class Wrapper { }

上面示例中,我們引入了 select 屬性,來選擇投射的內容:

<wrapper> <span>This is not a counter</span> <counter></counter></wrapper>

上述代碼成功運行后,counter 組件被正確投影到第二個藍色框中,而 span 元素最終會在全部紅色框中。請注意,目標 ng-content 會優先于 catch-all,即使它在模板中的位置靠后。

ngProjectAs

有時你的內部組件會被隱藏在另一個更大的組件中。有時你只需要將其包裝在額外的容器中即可應用 ngIf ngSwitch。無論什么原因,通常情況下,你的內部組件不是包裝器的直接子節點。為了演示上述情況,我們將 Counter 組件包裝在一個 <ng-container> 中,看看我們的目標投影會發生什么:

<wrapper> <ng-container>  <counter></counter> </ng-container></wrapper>

現在我們的 couter 組件會被投影到第一個紅色框中。因為 ng-container 容器不再匹配 select="counter"。為了解決這個問題,我們必須使用 ngProjectAs 屬性,它可以應用于任何元素上。具體如下:

<wrapper> <ng-container ngProjectAs="counter">  <counter></counter> </ng-container></wrapper>

通過設置 ngProjectAs 屬性,終于讓我們的 counter 組件重回藍色框的懷抱了。

Time to poke and prod

我們從一個簡單的實驗開始:將兩個 <ng-content> 塊放在我們的模板中,沒有選擇器。會出現什么情況?

頁面中會顯示一個或兩個框,如果我們包含兩個框,它們的內容是顯示 1 和 1 或 1 和 2?

<div class="box red">  <ng-content></ng-content></div><div class="box blue">  <ng-content></ng-content></div>

答案是我們在最后一個 <ng-content> 中得到一個計數器,另一個是空的!在我們嘗試解釋為什么之前,讓我們再來驗證一個問題,即在 ng-content 指令的外層容器中添加 ngIf 指令:

import { Component } from '@angular/core';@Component({ selector: 'wrapper', template: `  <button (click)="show = !show">   {{ show ? 'Hide' : 'Show' }}  </button>  <div class="box" *ngIf="show">   <ng-content></ng-content>  </div> `})class Wrapper { show = true;}

乍一看,似乎正常運行。但是如果你通過按鈕進行切換操作,你會注意到計數器的值不會增加。這意味著我們的計數器組件只被實例化了一次 - 從未被銷毀和重新創建。難道這是 ngIf 指令產生的問題,讓我們測試一下 ngFor 指令,看看是否有同樣的問題:

import { Component } from '@angular/core';@Component({ selector: 'wrapper', template: `  <div class="box" *ngFor="let item of items">   <ng-content></ng-content>  </div> `})class Wrapper { items = [0, 0, 0];}

以上代碼運行后與我們使用多個 <ng-content> 的效果是一樣的,只會顯示一個計數器!為什么不按照我們的預期運行?

The explanation

<ng-content> 不會 "產生" 內容,它只是投影現有的內容。你可以認為它等價于 node.appendChild(el) 或 jQuery 中的 $(node).append(el) 方法:使用這些方法,節點不被克隆,它被簡單地移動到它的新位置。因此,投影內容的生命周期將被綁定到它被聲明的地方,而不是顯示在地方。

這種行為有兩個原因:期望一致性和性能。什么 "期望的一致性" 意味著作為開發人員,可以基于應用程序的代碼,猜測其行為。假設我寫了以下代碼:

<div class="my-wrapper"> <counter></counter></div>

很顯然計數器將被實例化一次,但現在假如我們使用第三方庫的組件:

<third-party-wrapper> <counter></counter></third-party-wrapper>

如果第三方庫能夠控制 counter 組件的生命周期,我將無法知道它被實例化了多少次。其中唯一方法就是查看第三方庫的代碼,了解它們的內部處理邏輯。將組件的生命周期被綁定到我們的應用程序組件而不是包裝器的意義是,開發者可以掌控計數器只被實例化一次,而不用了解第三方庫的內部代碼。

性能的原因更為重要。因為 ng-content 只是移動元素,所以可以在編譯時完成,而不是在運行時,這大大減少了實際應用程序的工作量。

The solution

為了讓包裝器能夠控制其子元素的實例化,我們可以通過兩種方式完成:在我們的內容周圍使用 <ng-template> 元素,或者使用帶有 "*" 語法的結構指令。為簡單起見,我們將在示例中使用 <ng-template> 語法,我們的新應用程序如下所示:

<wrapper> <ng-template>  <counter></counter> </ng-template></wrapper>

包裝器不再使用 <ng-content>,因為它接收到一個模板。我們需要使用 @ContentChild 訪問模板,并使用ngTemplateOutlet 來顯示它:

@Component({ selector: 'wrapper', template: `  <button (click)="show = !show">   {{ show ? 'Hide' : 'Show' }}  </button>  <div class="box" *ngIf="show">   <ng-container [ngTemplateOutlet]="template"></ng-container>  </div> `})class Wrapper { show = true; @ContentChild(TemplateRef) template: TemplateRef;}

現在我們的 counter 組件,每當我們隱藏并重新顯示時都正確遞增!讓我們再驗證一下 *ngFor 指令:

@Component({ selector: 'wrapper', template: `  <div class="box" *ngFor="let item of items">   <ng-container [ngTemplateOutlet]="template"></ng-container>  </div> `})class Wrapper { items = [0, 0, 0]; @ContentChild(TemplateRef) template: TemplateRef;}

上面代碼成功運行后,每個盒子中有一個計數器,顯示 1,2 和 3,這正是我們之前預期的結果。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
尤物yw午夜国产精品视频| 国产一区二区成人| 国产亚洲欧美一区| 国产精品色午夜在线观看| 欧美日韩中文在线观看| 亚洲国产精品va在看黑人| 一区二区成人精品| 日韩在线视频导航| 在线播放日韩精品| 亚洲jizzjizz日本少妇| 久久精品久久精品亚洲人| 精品久久久久久久久久| 亚洲激情国产精品| 欧美日韩国产精品专区| 国产精品久久久久影院日本| 黄网动漫久久久| 在线精品视频视频中文字幕| 久久久久99精品久久久久| 亚洲福利视频二区| 国产精品美女无圣光视频| 国产成人精彩在线视频九色| 97**国产露脸精品国产| 大桥未久av一区二区三区| 久久久久国产一区二区三区| 91手机视频在线观看| 欧美专区福利在线| 国产精品黄页免费高清在线观看| 亚洲美女性视频| 久久久久久久久久久网站| 91精品国产91久久久久久最新| 国产第一区电影| 日韩欧美有码在线| 亚洲综合最新在线| 欧美床上激情在线观看| 在线日韩中文字幕| 国产成人a亚洲精品| 色综合91久久精品中文字幕| 国产成人精品av在线| 亚洲综合自拍一区| 午夜精品美女自拍福到在线| 欧美极品少妇xxxxⅹ裸体艺术| 992tv在线成人免费观看| 亚洲欧美日韩精品久久亚洲区| 国产亚洲欧美另类中文| 裸体女人亚洲精品一区| 国产日本欧美在线观看| 九九热r在线视频精品| 成人a在线观看| 亚洲福利在线观看| 91大神在线播放精品| 九九热这里只有在线精品视| 日本欧美精品在线| 国产97在线|日韩| 久久久久久午夜| 97精品国产97久久久久久| 欧美日韩国产第一页| 色偷偷噜噜噜亚洲男人的天堂| 亚洲的天堂在线中文字幕| 亚洲影院色无极综合| 中文字幕av一区中文字幕天堂| 国产精品伦子伦免费视频| 亚洲精品一区二区网址| 97在线视频观看| 亚洲欧美国产精品va在线观看| 欧美xxxx综合视频| 午夜精品99久久免费| 国产精品日韩在线播放| 日韩免费看的电影电视剧大全| 国产一区二区久久精品| 欧美日韩国产影院| 欧洲永久精品大片ww免费漫画| 欧美日韩国产二区| www.日本久久久久com.| 欧美精品电影免费在线观看| 国产精品亚洲网站| 国产精品成人一区二区三区吃奶| 精品国产一区二区三区久久狼5月| 国产精品久久二区| 2019精品视频| …久久精品99久久香蕉国产| 久久97精品久久久久久久不卡| 综合国产在线视频| 日韩免费av一区二区| 91精品国产777在线观看| 日韩国产在线播放| 欧美丝袜第一区| 久久久女人电视剧免费播放下载| 中文字幕亚洲综合久久筱田步美| 日韩av在线免费| 亚洲国产精品va在线观看黑人| 91高清视频在线免费观看| 日韩中文字幕在线免费观看| 97久久精品人搡人人玩| 国产精品吴梦梦| 国产精品吊钟奶在线| 狠狠躁天天躁日日躁欧美| 2019亚洲日韩新视频| 久久精品国产欧美亚洲人人爽| 精品国产一区二区三区久久狼黑人| 国产一区二区丝袜高跟鞋图片| 国产精品亚洲片夜色在线| 久久国产精品久久久久| 久久久久久亚洲精品| 日韩亚洲欧美中文在线| 亚洲美女黄色片| 国产日韩一区在线| 韩剧1988免费观看全集| 欧美日韩精品在线视频| 国模极品一区二区三区| 国产精品免费久久久久久| 国产美女精品免费电影| 成人免费淫片视频软件| 青青久久aⅴ北条麻妃| 色综合久久悠悠| 久久精品中文字幕| 国产成人精品一区二区三区| 亚洲欧洲一区二区三区在线观看| 国产精品久久久久久久久男| 96国产粉嫩美女| 国产精品久久久久久久午夜| 亚洲视频999| 亚洲精品按摩视频| 欧美xxxx综合视频| 777精品视频| 欧美三级xxx| 久久久久国色av免费观看性色| 国产一区二区三区视频免费| 国产福利视频一区二区| 57pao国产精品一区| 97av在线视频免费播放| 色午夜这里只有精品| 亚洲精品国产欧美| 日韩av免费看| 亚洲高清免费观看高清完整版| 欧美在线视频在线播放完整版免费观看| 国产啪精品视频| 亚洲色图激情小说| 亚洲电影免费观看高清完整版| 日韩中文字幕国产精品| 中文字幕综合一区| 一区二区福利视频| 国产在线98福利播放视频| 国产精品久久久久秋霞鲁丝| 欧美午夜影院在线视频| 国产精品第七影院| 78m国产成人精品视频| 成人夜晚看av| 色999日韩欧美国产| 欧美一区二区三区图| www欧美xxxx| 国产成人免费91av在线| 久久久久亚洲精品| 久久久久中文字幕2018| 亚洲二区在线播放视频| 久久视频免费在线播放| 自拍偷拍免费精品| 亚洲综合中文字幕68页| 亚洲成人1234| 久久精品国产亚洲精品| 国产精品午夜一区二区欲梦| 国产精品久久久久久久天堂| 岛国av一区二区| 中文字幕欧美在线| 亚洲免费av网址|