Angular 向組件傳遞模板的兩種方法
最近在寫一個日期選擇器組件,為了滿足將來可能出現(xiàn)的各種需求,所以需要能夠高度的自定義組件的樣式。為了達(dá)到這個目的,需要能夠在日期選擇器組件外控制每個日期格子內(nèi)要顯示的內(nèi)容,比如,標(biāo)上節(jié)假日之類的。這時候,組件的一部分模板就需要由調(diào)用方提供。
在 React 里面,這種需求挺簡單的,只要實(shí)現(xiàn)一個 date => Element
這樣的函數(shù)就好了,但是 Angular 模板是純粹的模板,需要使用一些專門的概念才能實(shí)現(xiàn)這個功能。
第一種方式 <ng-content>
<ng-content> 這個標(biāo)簽到本文撰寫時為止,還沒有官方的文檔,甚至連占位符都沒有。但是這并不妨礙我們的使用,外國熱心網(wǎng)友已經(jīng)總結(jié)出了 <ng-content> 在現(xiàn)階段的特點(diǎn)與作用。
基本用法
<!-- Wrapper.Component.html --> <div> hello <ng-content></ng-content> </div>
假設(shè)我們有一個上述的組件,然后向下面這樣調(diào)用:
<wrapper> <span> World </span> </wrapper>
那么最終的渲染結(jié)果將會是這樣的:
<div> hello <span> World </span> </div>
看起來就是發(fā)生了很簡單的替換,但是如果在 Wrapper 中出現(xiàn)了多個 <ng-content>
會出現(xiàn)多個 <span> World </span> 嗎?答案是不會的。<ng-content>
的本質(zhì)只是移動元素,并不會去自動的創(chuàng)建傳入的模板,所以就算用 ngFor 套住 <ng-content>
也不會出現(xiàn)很多個 <span> World </span>。如果傳入的是自定義的組件,這些組件也只會被實(shí)例化一次。
進(jìn)階用法
當(dāng)然,如果 <ng-content>
的功能僅僅只是這樣就顯得太雞肋了,在使用 <ng-content>
的時候可以指定一個選擇器,這個選擇器可以捕獲相符的直接子元素。例如:
<!-- Wrapper.Component.html --> <div> hello <ng-content></ng-content> <hr/> <ng-content select="span"></ng-content> </div>
然后像下面這樣使用:
<wrapper> <span> World </span> 2333 </wrapper>
最終的渲染結(jié)果將會是這樣:
<div> hello 2333 <hr/> <span> World </span> </div>
除了設(shè)置 ng-content
標(biāo)簽的 select 屬性之外,還可以在子元素上使用 ngProjectAs 屬性,這個屬性可以讓這個元素被父元素中指定的 ng-content 所捕獲。舉個例子:
<wrapper> <div ngProjectAs="span"> World </div> 2333 </wrapper>
這次被傳入的模板變成了一個 div,但是因?yàn)樵O(shè)置了 ngProjectAs,所以“World”會出現(xiàn)在分割線下方。
第二種方式 NgTemplateOutlet 指令
使用 ng-content
確實(shí)可以起到傳入模板的效果,但是卻有個很致命的問題,就是無法傳遞數(shù)據(jù)到傳入的模板中。為了將數(shù)據(jù)傳遞到傳入的模板中,就需要使用到 NgTemplateOutlet 指令。
基本使用
這個指令可以用來在模板的指定位置實(shí)例化一個 TemplateRef 對象,同時,在實(shí)例化的過程中還可以傳入一個數(shù)據(jù)對象。而 TemplateRef 可以通過 ng-template 標(biāo)簽來創(chuàng)建,舉個例子:
@Component({ selector: 'ng-template-outlet-example', template: ` <ng-container *ngTemplateOutlet="name; context: myContext"></ng-container> <ng-template #name let-name="data"><span>Hello {{name}}!</span></ng-template> ` }) class NgTemplateOutletExample { myContext = {data: 'World'}; }
ng-container
是一個虛擬的元素,在這個元素上我們使用了一個 NgTemplateOutlet 指令,指定了要實(shí)例化下面的名為 name 的 ng-template。同時把 myContext 這個對象作為實(shí)例化的數(shù)據(jù)上下文傳入,所以最終就會顯示 “Hello World!”。值得注意的是在 ng-template 里面獲取傳輸?shù)臄?shù)據(jù)上下文的方式:let-variableName='key'
。
進(jìn)階使用
接下來就要實(shí)現(xiàn)本文開頭提到的需求了,在組件外部傳入模板。還是以上面的例子為例,因?yàn)槟0逍枰赏饨缱鳛樽觾?nèi)容傳入,所以需要我們手動來捕獲模板,這里需要就需要使用 ContentChild:
@Component({ selector: 'wrapper', template: ` <ng-container *ngTemplateOutlet="name; context: myContext"></ng-container> ` }) class NgTemplateOutletExample { @ContentChild(TemplateRef) name: TemplateRef<any>; myContext = {data: 'World'}; }
就是這么簡單的改動就可以讓我們的組件從外界接受模板了,來試一試:
<wrapper> <ng-template let-value="data"> <span>Hello {{value}}!</span> </ng-template> </wrapper>
總結(jié)
以上就是 Angular 中向組件傳遞模板的兩種方法,其中,使用 <ng-content>
標(biāo)簽可以更方便的控制傳入的模板在 DOM 中的位置,而 NgTemplateOutlet 可以向傳入的模板傳遞渲染數(shù)據(jù),兩者搭配使用可以起到很好的效果。
以上所述是小編給大家介紹的Angular 向組件傳遞模板的兩種方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
AngularJS實(shí)用基礎(chǔ)知識_入門必備篇(推薦)
下面小編就為大家?guī)硪黄狝ngularJS實(shí)用基礎(chǔ)知識_入門必備篇(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07使用Angular內(nèi)置模塊進(jìn)行HTTP請求
這篇文章主要介紹了使用Angular內(nèi)置模塊進(jìn)行HTTP請求方法步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Angular實(shí)現(xiàn)的自定義模糊查詢、排序及三角箭頭標(biāo)注功能示例
這篇文章主要介紹了Angular實(shí)現(xiàn)的自定義模糊查詢、排序及三角箭頭標(biāo)注功能,涉及AngularJS針對頁面table元素的遍歷、查詢、判斷、排序等相關(guān)操作技巧,需要的朋友可以參考下2017-12-12AngularJS基礎(chǔ) ng-model-options 指令簡單示例
本文主要介紹AngularJS ng-model-options 指令,這里對ng-model-options指令的基本資料進(jìn)行整理,有需要的小伙伴可以參考下2016-08-08實(shí)踐中學(xué)習(xí)AngularJS表單
表單是最常用的一種組建。在Angular.js中,其實(shí)并沒有單獨(dú)的為表單添加多少特殊功能。但是,利用Angular.js框架本身的特點(diǎn),可以更友好的呈現(xiàn)表單。下面將介紹幾種常用的功能在Angular中是如何巧妙實(shí)現(xiàn)的2016-03-03用Angular實(shí)現(xiàn)一個掃雷的游戲示例
這篇文章主要介紹了用Angular實(shí)現(xiàn)一個掃雷的游戲示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05AngularJS基礎(chǔ) ng-value 指令簡單示例
本文主要介紹AngularJS ng-value 指令,這里對ng-value 的基礎(chǔ)資料做了整理,并附實(shí)例代碼,有需要的小伙伴可以參考下2016-08-08AngularJS使用$http配置對象方式與服務(wù)端交互方法
今天小編就為大家分享一篇AngularJS使用$http配置對象方式與服務(wù)端交互方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08AngularJS基于ngInfiniteScroll實(shí)現(xiàn)下拉滾動加載的方法
這篇文章主要介紹了AngularJS基于ngInfiniteScroll實(shí)現(xiàn)下拉滾動加載的方法,結(jié)合實(shí)例形式分析AngularJS下拉滾動插件ngInfiniteScroll的下載、功能、屬性及相關(guān)使用方法,需要的朋友可以參考下2016-12-12