這篇文章主要介紹了Angular 向組件傳遞模板的兩種方法,第一種方式<ng-content>第二種方式是NgTemplateOutlet 指令及各種使用方式介紹,需要的朋友可以參考下
最近在寫一個日期選擇器元件,為了滿足將來可能出現的各種需求,所以需要能夠高度的自訂元件的樣式。為了達到這個目的,需要能夠在日期選擇器元件外控制每個日期格子內要顯示的內容,比如,標上假日之類的。這時候,元件的一部分模板就需要由呼叫方提供。
在React 裡面,這種需求挺簡單的,只要實作一個date => Element
這樣的函數就好了,但是Angular 模板是純粹的模板,需要使用一些專門的概念才能實現這個功能。
第一種方法<ng-content>
#<ng-content> 這個標籤到本文撰寫時為止,還沒有官方的文檔,甚至連佔位符都沒有。但這並不妨礙我們的使用,外國熱心網友已經總結了 <ng-content> 在現階段的特徵與作用。
基本用法
<!-- Wrapper.Component.html --> <p> hello <ng-content></ng-content> </p>
假設我們有一個上述的元件,然後向下面這樣呼叫:
<wrapper> <span> World </span> </wrapper>
那麼最終的渲染結果將會是這樣的:
<p> hello <span> World </span> </p>
看起來就是發生了很簡單的替換,但是如果在Wrapper 中出現了多個 <ng-content>
會出現多個 World 嗎?答案是不會的。 <ng-content>
的本質只是移動元素,並不會去自動的創建傳入的模板,所以就算用ngFor 套住<ng-content>
也不會出現很多 World 。如果傳入的是自訂的元件,這些元件也只會被實例化一次。
進階用法
當然,如果<ng-content>
的功能只是這樣就顯得太雞肋了,在使用<ng-content>
的時候可以指定一個選擇器,這個選擇器可以捕捉相符的直接子元素。例如:
<!-- Wrapper.Component.html --> <p> hello <ng-content></ng-content> <hr/> <ng-content select="span"></ng-content> </p>
然後像下面這樣使用:
<wrapper> <span> World </span> 2333 </wrapper>
最終的渲染結果將會是這樣:
<p> hello 2333 <hr/> <span> World </span> </p>
除了設定ng-content
標籤的select 屬性之外,還可以在子元素上使用ngProjectAs 屬性,這個屬性可以讓這個元素被父元素中指定的ng-content 所捕捉。舉個例子:
<wrapper> <p ngProjectAs="span"> World </p> 2333 </wrapper>
這次被傳入的模板變成了一個 p,但因為設定了 ngProjectAs,所以「World」會出現在分割線下方。
第二種方式NgTemplateOutlet 指令
#使用ng-content
確實可以起到傳入模板的效果,但是卻有個很致命的問題,就是無法將資料傳遞到傳入的模板中。為了將資料傳遞到傳入的範本中,就需要使用到 NgTemplateOutlet 指令。
基本上使用
這個指令可以用來在模板的指定位置實例化一個TemplateRef 對象,同時,在實例化的過程中還可以傳入一個數據對象。而TemplateRef 可以透過ng-template 標籤來創建,舉個例子:
@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 指令,指定了要實例化下面的名為name 的ng-template。同時把 myContext 這個物件當作實例化的資料上下文傳入,所以最後就會顯示 「Hello World!」。值得注意的是在 ng-template 裡面取得傳輸的資料上下文的方式:let-variableName='key'
。
進階使用
接下來就要實現本文開頭提到的需求了,在元件外部傳入範本。還是以上面的例子為例,因為模板需要由外界作為子內容傳入,所以需要我們手動來捕獲模板,這裡需要就需要使用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>
上面是我整理給大家的,希望今後會對大家有幫助。
相關文章:
以上是在Angular中向組件傳遞模板的詳細內容。更多資訊請關注PHP中文網其他相關文章!