看了Angular官網(wǎng)Hero教程中的動態(tài)組件一節(jié)监右,然后還看了一篇講的不錯(cuò)的文章埂伦,結(jié)合自己的理解顿涣,總結(jié)Angular動態(tài)組件加載如下:
首先我們抽象地考慮一下,動態(tài)組件加載需要哪些東西一喘?首先你要加載的組件們應(yīng)該定義出來驱还,其次你需要一個(gè)可以掛載這些動態(tài)組件的容器嗜暴,并且要考慮怎么把你的組件掛載到容器上。
定義組件很容易议蟆,我們這里定義兩個(gè)最簡單的組件:
動態(tài)組件1:
動態(tài)組件2:
定義好的組件必須要在module里的declarations和entryComponents中聲明:
Angular中凡是要用到的組件都要在declarations中聲明這好理解闷沥,但是為什么要在entryComponents里面也要去聲明呢?別忘了我們的組件是動態(tài)組件咐容,這意味著angular根本不知道我們在運(yùn)行時(shí)要加載哪些動態(tài)組件舆逃,所以angular在編譯階段不會為這些動態(tài)組件進(jìn)行實(shí)例化,但是當(dāng)運(yùn)行時(shí)我們需要它的時(shí)候戳粒,angular得知道啊路狮,這里就告訴angular這些是動態(tài)組件,需要在運(yùn)行的時(shí)候給我臨時(shí)創(chuàng)建蔚约。其實(shí)在entryComponents里聲明的組件奄妨,angular都會創(chuàng)建一個(gè)工廠(ComponentFactory)并且存儲在ComponentFactoryResolver(相當(dāng)于一個(gè)工廠集合)中,然后在需要的時(shí)候由工廠去創(chuàng)建這些動態(tài)組件炊琉,后面會詳細(xì)說明展蒂。
然后我們就來看看怎么去把這些動態(tài)組件掛載到視圖容器中又活。我們定義了一個(gè)DynamicComponent的組件如下:
我們這個(gè)組件用一個(gè)定時(shí)器去不斷循環(huán)加載我們定義的兩個(gè)動態(tài)組件苔咪,用@ViewChild獲取模板中的<section>節(jié)點(diǎn)作為加載的容器,其中{read: ContainerRef}是說把這個(gè)節(jié)點(diǎn)當(dāng)作ContainerRef進(jìn)行解釋柳骄,因?yàn)镃ontainerRef可以去掛載組件团赏。我們依賴注入了ComponentFactoryResolver,用它來獲取動態(tài)組件的工廠耐薯,然后ContainerRef調(diào)用createComponent完成兩件事:1.利用動態(tài)組件的工廠創(chuàng)建出動態(tài)組件的實(shí)例舔清,2. 把動態(tài)組件的實(shí)例掛載到ContainerRef中。
至此提一個(gè)問題曲初,為什么Angular實(shí)現(xiàn)動態(tài)組件要用工廠模式而不直接new呢体谒?從上面可以看到,其實(shí)動態(tài)組件不僅僅是需要?jiǎng)?chuàng)建它的實(shí)例臼婆,還需要考慮如何去加載動態(tài)組件到它的宿主元素上抒痒,甚至還有其他的一些額外操作,所以如果我們僅僅是new一個(gè)組件颁褂,那么只是組件的一個(gè)很小的部分故响,或者說只是初始化了組件中的‘一些變量,而組件的很多其他內(nèi)容颁独,包括很多DOM操作都沒有去做彩届,而利用組件工廠,angular恰恰幫我們?nèi)プ隽诉@些事情誓酒,屏蔽了諸如DOM操作的相關(guān)內(nèi)容樟蠕,所以我們要用工廠模式去解決動態(tài)組件的問題。