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

淺談angular4 ng-content 中隱藏的內(nèi)容

 更新時(shí)間:2017年08月18日 14:48:09   投稿:zx  
本篇文章主要介紹了淺談angular4 ng-content 中隱藏的內(nèi)容,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

如果你嘗試在 Angular 中編寫可重復(fù)使用的組件,則可能會(huì)接觸到內(nèi)容投射的概念。然后你發(fā)現(xiàn)了 <ng-content> ,并找到了一些關(guān)于它的文章,進(jìn)而實(shí)現(xiàn)了所需的功能。

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

Simple example

在本文中我們使用一個(gè)示例,來演示不同的方式實(shí)現(xiàn)內(nèi)容投影。由于許多問題與Angular 中的組件生命周期相關(guān),因此我們的主要組件將顯示一個(gè)計(jì)數(shù)器,用于展示它已被實(shí)例化的次數(shù):

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 屬性用于顯示本組件被實(shí)例化的次數(shù)。接著我們繼續(xù)定義一個(gè) Wrapper 組件:

import { Component } from '@angular/core';

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

現(xiàn)在我們來驗(yàn)證一下效果:

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

Targeted projection

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

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 屬性,來選擇投射的內(nèi)容:

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

上述代碼成功運(yùn)行后,counter 組件被正確投影到第二個(gè)藍(lán)色框中,而 span 元素最終會(huì)在全部紅色框中。請(qǐng)注意,目標(biāo) ng-content 會(huì)優(yōu)先于 catch-all,即使它在模板中的位置靠后。

ngProjectAs

有時(shí)你的內(nèi)部組件會(huì)被隱藏在另一個(gè)更大的組件中。有時(shí)你只需要將其包裝在額外的容器中即可應(yīng)用 ngIf ngSwitch。無論什么原因,通常情況下,你的內(nèi)部組件不是包裝器的直接子節(jié)點(diǎn)。為了演示上述情況,我們將 Counter 組件包裝在一個(gè) <ng-container> 中,看看我們的目標(biāo)投影會(huì)發(fā)生什么:

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

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

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

通過設(shè)置 ngProjectAs 屬性,終于讓我們的 counter 組件重回藍(lán)色框的懷抱了。

Time to poke and prod

我們從一個(gè)簡單的實(shí)驗(yàn)開始:將兩個(gè) <ng-content> 塊放在我們的模板中,沒有選擇器。會(huì)出現(xiàn)什么情況?

頁面中會(huì)顯示一個(gè)或兩個(gè)框,如果我們包含兩個(gè)框,它們的內(nèi)容是顯示 1 和 1 或 1 和 2?

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

答案是我們?cè)谧詈笠粋€(gè) <ng-content> 中得到一個(gè)計(jì)數(shù)器,另一個(gè)是空的!在我們嘗試解釋為什么之前,讓我們?cè)賮眚?yàn)證一個(gè)問題,即在 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;
}

乍一看,似乎正常運(yùn)行。但是如果你通過按鈕進(jìn)行切換操作,你會(huì)注意到計(jì)數(shù)器的值不會(huì)增加。這意味著我們的計(jì)數(shù)器組件只被實(shí)例化了一次 - 從未被銷毀和重新創(chuàng)建。難道這是 ngIf 指令產(chǎn)生的問題,讓我們測試一下 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];
}

以上代碼運(yùn)行后與我們使用多個(gè) <ng-content> 的效果是一樣的,只會(huì)顯示一個(gè)計(jì)數(shù)器!為什么不按照我們的預(yù)期運(yùn)行?

The explanation

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

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

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

很顯然計(jì)數(shù)器將被實(shí)例化一次,但現(xiàn)在假如我們使用第三方庫的組件:

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

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

性能的原因更為重要。因?yàn)?code> ng-content 只是移動(dòng)元素,所以可以在編譯時(shí)完成,而不是在運(yùn)行時(shí),這大大減少了實(shí)際應(yīng)用程序的工作量。

The solution

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

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

包裝器不再使用 <ng-content>,因?yàn)樗邮盏揭粋€(gè)模板。我們需要使用 @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;
}

現(xiàn)在我們的 counter 組件,每當(dāng)我們隱藏并重新顯示時(shí)都正確遞增!讓我們?cè)衮?yàn)證一下 *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;
}

上面代碼成功運(yùn)行后,每個(gè)盒子中有一個(gè)計(jì)數(shù)器,顯示 1,2 和 3,這正是我們之前預(yù)期的結(jié)果。

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

相關(guān)文章

  • Angular自定義組件實(shí)現(xiàn)數(shù)據(jù)雙向數(shù)據(jù)綁定的實(shí)例

    Angular自定義組件實(shí)現(xiàn)數(shù)據(jù)雙向數(shù)據(jù)綁定的實(shí)例

    下面小編就為大家分享一篇Angular自定義組件實(shí)現(xiàn)數(shù)據(jù)雙向數(shù)據(jù)綁定的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • 深入理解Angularjs中$http.post與$.post

    深入理解Angularjs中$http.post與$.post

    本篇文章主要介紹了深入理解Angularjs中$http.post與$.post ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • angular2 ng2 @input和@output理解及示例

    angular2 ng2 @input和@output理解及示例

    本篇文章主要介紹了angular2 ng2 @input和@output理解及示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • angularJS 中input示例分享

    angularJS 中input示例分享

    這篇文章主要介紹了angularJS 中input示例分享,需要的朋友可以參考下
    2015-02-02
  • AngularJS手動(dòng)表單驗(yàn)證

    AngularJS手動(dòng)表單驗(yàn)證

    這篇文章主要介紹了AngularJS手動(dòng)表單驗(yàn)證的相關(guān)資料,AngularJS的表單驗(yàn)證大致有兩種,一種是手動(dòng)驗(yàn)證,一種是自動(dòng)驗(yàn)證,本文重點(diǎn)介紹AngularJS手動(dòng)表單驗(yàn)證,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 淺談Angular.js中使用$watch監(jiān)聽模型變化

    淺談Angular.js中使用$watch監(jiān)聽模型變化

    當(dāng)angular數(shù)據(jù)模型發(fā)生變化時(shí),我們需要如果需要根據(jù)他的變化觸發(fā)其他的事件。本篇文章主要介紹了Angular.js中使用$watch監(jiān)聽模型變化,有興趣的可以了解一下
    2017-01-01
  • Angular4.0動(dòng)畫操作實(shí)例詳解

    Angular4.0動(dòng)畫操作實(shí)例詳解

    這篇文章主要介紹了Angular4.0動(dòng)畫操作,結(jié)合實(shí)例形式詳細(xì)分析了Angular4.0動(dòng)畫的原理、定義及使用等相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • AngularJS基礎(chǔ) ng-include 指令簡單示例

    AngularJS基礎(chǔ) ng-include 指令簡單示例

    本文主要介紹AngularJS ng-include 指令,這里對(duì)ng-include的基本知識(shí)做了整理,并附有代碼實(shí)例,有需要的朋友可以參考下
    2016-08-08
  • 解決Angular2 router.navigate刷新頁面的問題

    解決Angular2 router.navigate刷新頁面的問題

    今天小編就為大家分享一篇解決Angular2 router.navigate刷新頁面的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Angular 組件之間的交互的示例代碼

    Angular 組件之間的交互的示例代碼

    這篇文章主要介紹了Angular 組件之間的交互的示例代碼,根據(jù)數(shù)據(jù)的傳遞方向,分為父組件向子組件傳遞、子組件向父組件傳遞及通過服務(wù)傳遞三種交互方法。非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-03-03

最新評(píng)論