成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Angular開發(fā)實(shí)踐(八): 使用ng-content進(jìn)行組件內(nèi)容投射

leo108 / 1216人閱讀

摘要:假設(shè)我寫了以下代碼很顯然組件將被實(shí)例化一次,但現(xiàn)在假如我們使用第三方庫的組件如果第三方庫能夠控制組件的生命周期,我將無法知道它被實(shí)例化了多少次。

在Angular中,組件屬于特殊的指令,它的特殊之處在于它有自己的模板(html)和樣式(css)。因此使用組件可以使我們的代碼具有強(qiáng)解耦、可復(fù)用、易擴(kuò)展等特性。通常的組件定義如下:

demo.component.ts:

import { Component, OnInit } from "@angular/core";

@Component({
    selector: "demo-component",
    templateUrl: "./demo.component.html",
    styleUrls: ["./demo.component.scss"]
})
export class DemoComponent implements OnInit {

    constructor() {
    }

    ngOnInit() {
    }
}

demo.component.html:

demo-component - 我是一個(gè)簡(jiǎn)單的組件

demo.component.scss:

.demo {
    padding: 10px;
    border: 2px solid red;

    h2 {
        margin: 0;
        color: #262626;
    }
}

此時(shí)我們引用該組件,就會(huì)呈現(xiàn)該組件解析之后的內(nèi)容:

假設(shè)現(xiàn)在有這樣的需求,這個(gè)組件能夠接受外部投射進(jìn)來的內(nèi)容,也就是說組件最終呈現(xiàn)的內(nèi)容不僅僅是本身定義的那些,那該怎么做呢?這時(shí)就要請(qǐng)出本文的主角 ng-content。

簡(jiǎn)單投射

我們先從最簡(jiǎn)單開始,在 demo.component.html 中添加 ,修改后的 demo.component.html 和 demo.component.scss 如下:

demo.component.html:

demo-component - 可嵌入外部?jī)?nèi)容的組件

demo.component.scss:

.demo {
    padding: 10px;
    border: 2px solid red;

    h2 {
        margin: 0;
        color: #262626;
    }

    .content {
        padding: 10px;
        margin-top: 10px;
        line-height: 20px;
        color: #FFFFFF;
        background-color: #de7d28;
    }
}

為了效果展示特意將 所在的容器背景色定義為橙色。

這時(shí)我們?cè)谝迷摻M件時(shí)可以從外部投射內(nèi)容,外部?jī)?nèi)容將在橙色區(qū)域顯示:


    我是外部嵌入的內(nèi)容

針對(duì)性投射

如果同時(shí)存在幾個(gè) ,那外部?jī)?nèi)容將如何進(jìn)行投射呢?

我們先看個(gè)示例,為了區(qū)別,我再新增一個(gè)藍(lán)色區(qū)域的 ,修改后的 demo.component.html 和 demo.component.scss 如下:

demo.component.html:

demo-component - 可嵌入外部?jī)?nèi)容的組件

demo.component.scss:

.demo {
    padding: 10px;
    border: 2px solid red;

    h2 {
        margin: 0;
        color: #262626;
    }

    .content {
        padding: 10px;
        margin-top: 10px;
        line-height: 20px;
        color: #FFFFFF;
        background-color: #de7d28;
        
        &.blue {
            background-color: blue;
        }
    }
}

引用該組件:


    我是外部嵌入的內(nèi)容

此時(shí),我們將看到外部?jī)?nèi)容投射到了藍(lán)色區(qū)域:

當(dāng)然,如果你將橙色區(qū)域代碼放在藍(lán)色區(qū)域代碼的后面,那么外部?jī)?nèi)容就會(huì)投射到橙色區(qū)域:

所以從上面的示例我們可以看出,如果同時(shí)存在簡(jiǎn)單的 ,那么外部?jī)?nèi)容將投射在組件模板最后的那個(gè) 中。

那么知道這個(gè)問題,我們可能會(huì)想,能不能將外部?jī)?nèi)容有針對(duì)性的投射相應(yīng)的 中呢?答案顯然是可以的。

為了處理這個(gè)問題, 支持一個(gè) select 屬性,可以讓你在特定的地方投射具體的內(nèi)容。該屬性支持 CSS 選擇器(標(biāo)簽選擇器、類選擇器、屬性選擇器、...)來匹配你想要的內(nèi)容。如果 ng-content 上沒有設(shè)置 select 屬性,它將接收全部?jī)?nèi)容,或接收不匹配任何其他 ng-content 元素的內(nèi)容。

直接看例子,修改后的 demo.component.html 和 demo.component.scss 如下:

demo.component.html:

demo-component - 可嵌入外部?jī)?nèi)容的組件

demo.component.scss:

.demo {
    padding: 10px;
    border: 2px solid red;

    h2 {
        margin: 0;
        color: #262626;
    }

    .content {
        padding: 10px;
        margin-top: 10px;
        line-height: 20px;
        color: #FFFFFF;
        background-color: #de7d28;

        &.blue {
            background-color: blue;
        }

        &.red {
            background-color: red;
        }

        &.green {
            background-color: green;
        }
    }
}

從上面代碼可以看到,藍(lán)色區(qū)域?qū)⒔邮?標(biāo)簽 header 那部分內(nèi)容,紅色區(qū)域?qū)⒔邮?class為"demo2"的div 的那部分內(nèi)容,綠色區(qū)域?qū)⒔邮?屬性name為"demo3"的div 的那部分內(nèi)容,橙色區(qū)域?qū)⒔邮掌溆嗟耐獠績(jī)?nèi)容(開始,我是外部嵌入的內(nèi)容,結(jié)束)。

引用該組件:


    開始,我是外部嵌入的內(nèi)容,
    
我是外部嵌入的內(nèi)容,我在header中
我是外部嵌入的內(nèi)容,我所在div的class為"demo2"
我是外部嵌入的內(nèi)容demo,我所在div的屬性name為"demo3"
結(jié)束

此時(shí),我們將看到外部?jī)?nèi)容投射到了指定的 中。

擴(kuò)展知識(shí) ngProjectAs

現(xiàn)在我們知道通過 ng-content 的 select 屬性可以指定外部?jī)?nèi)容投射到指定的 中。

而要能正確的根據(jù) select 屬性投射內(nèi)容,有個(gè)限制就是 - 不管是 標(biāo)簽 header、class為"demo2"的div還是 屬性name為"demo3"的div,這幾個(gè)標(biāo)簽都是作為 組件標(biāo)簽 直接子節(jié)點(diǎn)。

那如果不是作為直接子節(jié)點(diǎn),會(huì)是什么情況呢?我們簡(jiǎn)單修改下引用 demo-component 組件的代碼,將 標(biāo)簽header 放在一個(gè)div中,修改如下:


    開始,我是外部嵌入的內(nèi)容,
    
我是外部嵌入的內(nèi)容,我在header中
我是外部嵌入的內(nèi)容,我所在div的class為"demo2"
我是外部嵌入的內(nèi)容demo,我所在div的屬性name為"demo3"
結(jié)束

此時(shí),我們看到 標(biāo)簽 header 那部分內(nèi)容不再投射到藍(lán)色區(qū)域中了,而是投射到橙色區(qū)域中了。原因就是 無法匹配到之前的 標(biāo)簽 header,故而將這部分內(nèi)容投射到了橙色區(qū)域的 中了。

為了解決這個(gè)問題,我們必須使用 ngProjectAs 屬性,它可以應(yīng)用于任何元素上。具體如下:


    開始,我是外部嵌入的內(nèi)容,
    
我是外部嵌入的內(nèi)容,我在header中
我是外部嵌入的內(nèi)容,我所在div的class為"demo2"
我是外部嵌入的內(nèi)容demo,我所在div的屬性name為"demo3"
結(jié)束

通過設(shè)置 ngProjectAs 屬性,讓 標(biāo)簽header 所在的 div 指向了 select="header",此時(shí) 標(biāo)簽 header 那部分內(nèi)容有投射到藍(lán)色區(qū)域了:

不“產(chǎn)生”內(nèi)容 做個(gè)試驗(yàn)

做個(gè)試驗(yàn),先定義一個(gè) demo-child-component 組件:

import { Component, OnInit } from "@angular/core";

@Component({
    selector: "demo-child-component",
    template: "

我是demo-child-component組件

" }) export class DemoChildComponent implements OnInit { constructor() { } ngOnInit() { console.log("demo-child-component初始化完成!"); } }

demo-component 組件修改為:

import { Component, OnInit } from "@angular/core";

@Component({
    selector: "demo-component",
    template: `
        
        
` }) export class DemoComponent implements OnInit { show = true; constructor() { } ngOnInit() { } }

然后在 demo-component 中 投射 demo-child-component:


    

此時(shí),在控制臺(tái)我們看到打印出 demo-child-component初始化完成! 這些文字。但是當(dāng)我們點(diǎn)擊按鈕進(jìn)行切換操作時(shí),demo-child-component初始化完成! 就不再打印了,這意味著我們的 demo-child-component 組件只被實(shí)例化了一次 - 從未被銷毀和重新創(chuàng)建。

為什么會(huì)出現(xiàn)這樣的情況呢?

出現(xiàn)原因

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

這也從原理解釋了前面那個(gè)問題:如果同時(shí)存在幾個(gè) ,那外部?jī)?nèi)容將如何進(jìn)行投射呢?

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


    

很顯然 demo-child-component 組件將被實(shí)例化一次,但現(xiàn)在假如我們使用第三方庫的組件:


    

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

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

解決方法

為了讓組件能夠控制投射進(jìn)來的子組件的實(shí)例化,我們可以通過兩種方式完成:在我們的內(nèi)容周圍使用 元素及 ngTemplateOutlet,或者使用帶有 "*" 語法的結(jié)構(gòu)指令。為簡(jiǎn)單起見,我們將在示例中使用 語法。

demo-component 組件修改為:

import { Component, OnInit } from "@angular/core";

@Component({
    selector: "demo-component",
    template: `
        
        
` }) export class DemoComponent implements OnInit { @ContentChild(TemplateRef) template: TemplateRef; show = true; constructor() { } ngOnInit() { } }

然后我們將 demo-child-component 包含在 ng-template 中:


    
        
    

此時(shí),我們?cè)邳c(diǎn)擊按鈕進(jìn)行切換操作時(shí),控制臺(tái)都會(huì)打印出 demo-child-component初始化完成! 這些文字。

參考資源

ng-content: The hidden docs

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93975.html

相關(guān)文章

  • AngularJs 入門(一)--前言

    摘要:入門一前言目前來說相對(duì)于現(xiàn)在流行的高版本以及來說實(shí)屬是老套的前端框架了,當(dāng)然這都不重要,沒有完美的框架,只有不斷優(yōu)化的代碼。通過使用我們稱為指令的結(jié)構(gòu),讓瀏覽器能夠識(shí)別新的語法。使用作為輸入,而不是字符串,是區(qū)別于其它的框架的最大原因。 AngularJs 入門(一) 前言 AngularJs目前來說相對(duì)于現(xiàn)在流行的高版本ng2、ng4,以及Vue2.0、React來說實(shí)屬是老套的前...

    wenyiweb 評(píng)論0 收藏0
  • 前端每周清單半年盤點(diǎn)之 Angular

    摘要:延伸閱讀學(xué)習(xí)與實(shí)踐資料索引與前端工程化實(shí)踐前端每周清單半年盤點(diǎn)之篇前端每周清單半年盤點(diǎn)之與篇前端每周清單半年盤點(diǎn)之篇 前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(hào)(ID:frontshow),及時(shí)獲取前端每周清單;本文則是對(duì)于半年來發(fā)布的前端每周清單...

    LeviDing 評(píng)論0 收藏0
  • 前端每周清單:Node.js 微服務(wù)實(shí)踐,Vue.js 與 GraphQL,Angular 組件技巧

    摘要:前端每周清單第期微服務(wù)實(shí)踐,與,組件技巧,攻防作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。 前端每周清單第 26 期:Node.js 微服務(wù)實(shí)踐,Vue.js 與 GraphQL,Angular 組件技巧,HeadlessChrome 攻防 作者:王下邀月熊 編輯:徐川...

    wall2flower 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<