這篇文章給大家介紹怎么在Angular中利用模板輸入變量,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),陵川企業(yè)網(wǎng)站建設(shè),陵川品牌網(wǎng)站建設(shè),網(wǎng)站定制,陵川網(wǎng)站建設(shè)報價,網(wǎng)絡營銷,網(wǎng)絡優(yōu)化,陵川網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
@Component({ selector: 'nz-demo-pagination-item-render', template: `` }) export class NzDemoPaginationItemRenderComponent {} {{ page }} Previous Next << >>
看完這個之后我就很是疑惑,這個let是啥,為啥let-
跟上一個變量之后就有值了呢?然后我就開始在官網(wǎng)中找這個let
是什么東西。最終,我在主要概念-指令-結(jié)構(gòu)性指令的微語法一節(jié)找到了關(guān)于let
的說明。官網(wǎng)描述:微語法?!鞠嚓P(guān)推薦:《angular教程》】
在下面還有一段簡短的說明:
模板輸入變量(Template input variable)
模板輸入變量是這樣一種變量,你可以在單個實例的模板中引用它的值。 這個例子中有好幾個模板輸入變量:
hero
、i
和odd
。 它們都是用let
作為前導關(guān)鍵字。......
你使用
let
關(guān)鍵字(如let hero
)在模板中聲明一個模板輸入變量。 這個變量的范圍被限制在所重復模板的單一實例上。 事實上,你可以在其它結(jié)構(gòu)型指令中使用同樣的變量名。......
官網(wǎng)還是一如既往的不說人話,短短幾句話就給你介紹完了,也不告訴你這玩意怎么用,也不告訴你let
聲明的變量的值到底是從哪里來的。我越看越氣,得,官網(wǎng)你不說,我自己找。
先說一個粗略的結(jié)論:let聲明的變量是這個template模板的上下文對象中的變量。不然為啥叫模板輸入變量呢。在*ngFor內(nèi)幕這小節(jié)中,我們了解到了其內(nèi)幕,結(jié)構(gòu)性指令其實就是將宿主元素包裹在一個
中,然后在這個模板上將*ngFor
中的表達式解析成一個個的let
模板輸入變量和這個指令需要傳入的值。由于模板中代碼并不會直接被渲染成視圖,所以一定需要某種方法來使模板變成視圖。我們的結(jié)構(gòu)性指令就是干這個事的,就是將我們的模板變成視圖。
*ngFor
的官方示例代碼如下:
//解析前的模板({{i}}) {{hero.name}}//angular解析后的模板 ({{i}}) {{hero.name}}
在此提示一下,所謂的宿主元素就是指令所在的那個元素,像上面的例子中,div
就是*ngFor
指令的宿主元素。
trackBy
這個類似于vue和react中的key??梢越o模板一個標識,使其重新渲染的時候性能開銷降低一些。
然后我們再看官網(wǎng)說的:
let-i
和let-odd
變量是通過let i=index
和let odd=odd
來定義的。 Angular 把它們設(shè)置為上下文對象中的index
和odd
屬性的當前值。這里并沒有指定
let-hero
的上下文屬性。它的來源是隱式的。 Angular 將let-hero
設(shè)置為此上下文中$implicit
屬性的值, 它是由NgFor
用當前迭代中的英雄初始化的。
看完這段描述,我們可以得知:angular為這個模板設(shè)置了上下文對象。但是我們看不到這個過程,因為這是在ngFor
的源碼內(nèi)部實現(xiàn)的。并且這個上下文對象具備index
和odd
屬性,并且包含一個$implicit
(implicit:含蓄的;不直接言明的)的屬性。那么我們推斷這個上下文對象至少有以下幾個屬性:
{ $implicit:null, index:null, odd:null, }
那么我們聲明let
變量的本質(zhì)其實就是聲明一個變量獲取上下文對象中的同名屬性的值。let-hero
不進行任何賦值的話,hero
默認等于$implicit
的值。無論是有多少個let-a
,let-b
,let-c
還是let-me
。聲明的這個變量的值都等于$implicit
的值。而我們進行賦值過的,比如let-i = "index"
,i
的值就等于這個上下文對象中的index
屬性對應的值。
當我們知道這個上下文對象是什么了,就該想這個上下文對象是怎么設(shè)置的了。
在結(jié)構(gòu)性指令這一節(jié)當中,我們跟著官方示例做了一遍這個自定義結(jié)構(gòu)性指令(如果還沒有做的話,建議先跟著做一遍)。在UnlessDirective
這個指令中,其構(gòu)造器constructor
聲明了兩個可注入的變量,分別是TemplateRef
和ViewContainerRef
。官網(wǎng)給的解釋我覺得太過晦澀難懂,我這里給出一下我自己的理解:TemplateRef
代表的是宿主元素被包裹之后形成的模板的引用。而ViewContainerRef
代表的是一個視圖容器的引用。那么問題來了,這個視圖容器在哪兒呢?我們在constructor
構(gòu)造器中打印一下ViewContainerRef
。打印結(jié)果如圖:
然后我們點進去這個comment
元素。發(fā)現(xiàn)其就是一個注釋元素。如圖所示:
其實我也不是很確定這個視圖容器到底是不是這個注釋元素。但是毋庸置疑的是,視圖容器和宿主元素是兄弟關(guān)系,緊挨著宿主元素。我們可以使用ViewContainerRef
中的createEmbeddedView()
方法(Embedded:嵌入式,內(nèi)嵌式),將templateRef
模板引用傳入進去,創(chuàng)建出來一個真實的視圖。由于這個視圖是被插入到視圖容器ViewContainerRef
中了,所以又叫內(nèi)嵌視圖。那么這又和我們的上下文對象有什么關(guān)系呢?其實createEmbeddedView
這個方法不止一個參數(shù),其第二個參數(shù)就是給我們的模板設(shè)置上下文對象的。API的詳情介紹請看createEmbeddedView這個API的詳情。
就這樣。我們就可以將上下文對象塞入模板中了,這樣的話我們也可以直接使用let聲明變量的方法來使用這個上下文對象了。
appRepeat
那么我們知道是如何設(shè)置的了,那么我們就來驗證一下是否是對的。接下來,我們仿照ngfor
的功能,自己寫一個簡單的渲染指令。
首先我們定義一個指令:RepeatDirective
。代碼如下:
@Directive({ selector: '[appRepeat]', }) export class RepeatDirective { constructor( private templateRef: TemplateRef, private viewContainer: ViewContainerRef, ) { } @Input() set appRepeatOf(heroesList: string[]) { heroesList.forEach((item, index, arr) => { this.viewContainer.createEmbeddedView(this.templateRef, { //當前條目的默認值 $implicit: item, //可迭代對象的總數(shù) count: arr.length, //當前條目的索引值 index: index, //如果當前條目在可迭代對象中的索引號為偶數(shù)則為 true。 even: index % 2 === 0, //如果當前條目在可迭代對象中的索引號為奇數(shù)則為 true。 odd: index % 2 === 1, }); }); } }
然后我們將其導入NgModule中,這個過程就省略不寫了。然后我們在組件中使用一下這個指令:
@Component({ selector: 'app-structural-likeNgFor-demo', template: `原神1.5版本卡池角色
自定義ngFor(appRepeat)
在這里需要注意的是指令中的appRepeatOf
不是亂寫的。在微語法的解析過程中let h of heroesList
中的of
首先首字母會變成大寫的,變成Of
。然后在給它加上這個指令的前綴,也就是appRepeat
。組合起來就是appRepeatOf
了。由它來接收一個可迭代的對象。
最后顯示的效果圖:
關(guān)于怎么在Angular中利用模板輸入變量就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。