最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

angular動(dòng)態(tài)表單制作

 更新時(shí)間:2018年02月23日 14:10:55   作者:野生爬山虎  
通過實(shí)例代碼給大家詳細(xì)講述了angular動(dòng)態(tài)表單的制作方法,對(duì)此有需要的朋友參考下。

源碼:https://github.com/Karin001/ngx-dynamic-form

動(dòng)態(tài)表單使用場景

有時(shí)候我們需要一個(gè)靈活的表單,這個(gè)表單可以根據(jù)用戶的選擇,或者服務(wù)器返回的信息進(jìn)行重新配置,比如:增加或刪除一組input元素、一組select元素,等等。

在這樣的情況下,如果一開始就在模板里寫下所有的表單,利用一個(gè)ngif樹狀結(jié)構(gòu)進(jìn)行選擇控制,程序會(huì)變得比較冗余。

這時(shí)。程序最好是能夠根據(jù)用戶的選擇(driven by configuration)或者服務(wù)器的響應(yīng),自動(dòng)生成所需要的表單。這就是動(dòng)態(tài)表單要處理的業(yè)務(wù)。

組件生成的相關(guān)概念組件的兩個(gè)構(gòu)成

要?jiǎng)討B(tài)生成表單,需要先理解組件是如何生成的。

一個(gè)angular組件由兩部分所組成。

Wrapper

Wrapper能夠與組件進(jìn)行交互,當(dāng)一個(gè)Wrapper初始化完成后,就已經(jīng)幫我們實(shí)例化了一個(gè)組件。同時(shí),它也負(fù)責(zé)組件的change detection,以及觸發(fā)鉤子函數(shù)比如ngOnInit,ngOnChanges。

View

View負(fù)責(zé)呈現(xiàn)渲染過后的模板,將組件的外貌展示出來,并且能夠觸發(fā)Wrapper的change detection。一個(gè)組件可以有多個(gè)view,每一個(gè)view可以通過調(diào)用angular提供的兩個(gè)函數(shù)自行生成和銷毀,這個(gè)過程不用頂層的視圖參與。

組件的通常加載方式(非動(dòng)態(tài)加載方式)

通常情況下,我們都是把組件內(nèi)嵌到根組件或者另一個(gè)組件當(dāng)中使用。嵌入的組件稱為子組件,被嵌入的稱為父組件。這時(shí),當(dāng)我們的子組件代碼在被編譯時(shí),會(huì)生成一個(gè)組件工廠component factory(這是angular核心類ComponentFactory的一個(gè)實(shí)例),和一個(gè)hsot view,host view負(fù)責(zé)本組件在父組件視圖內(nèi)生成該組件的dom節(jié)點(diǎn),以及生成該組件的wrapper和view。

動(dòng)態(tài)加載組件

而當(dāng)我們想要將一個(gè)動(dòng)態(tài)組件插入某個(gè)組件視圖時(shí),則無法取得這個(gè)動(dòng)態(tài)組件的實(shí)例,因?yàn)檫@些是非動(dòng)態(tài)組件編譯器做的事。

實(shí)現(xiàn)動(dòng)態(tài)組件

angular提供了一些函數(shù)解決上面的難題,要使用這些函數(shù)我們需要注入兩個(gè)對(duì)象。

constructor(
 private componentFactoryResolver: ComponentFactoryResolver,
 private viewcontainerRef: ViewContainerRef,
 ) {
  
 }

我們注入了ComponentFactoryResolver,和ViewContainerRef。

ComponentFactoryResolver上提供了一個(gè)方法(resolveComponentFactory()),該方法接收一個(gè)組件類作為參數(shù),生成一個(gè)基于該組件類的組件工廠,也就是我們之前提到的那個(gè)組件工廠。

ViewContainerRef提供了一個(gè)方法(createComponent()),該方法接收組件工廠作為參數(shù),在該視圖中生成子組件。(我個(gè)人的理解是它處理了host view所做的事,為組件生成了wrapper和view)

實(shí)現(xiàn)動(dòng)態(tài)表單

上文簡要的介紹了實(shí)現(xiàn)動(dòng)態(tài)組件的一些技術(shù),現(xiàn)在開始思考如何做一個(gè)動(dòng)態(tài)表單。

具體思路

我們想要做出一個(gè)獨(dú)立的動(dòng)態(tài)表單模塊,當(dāng)我們想要使用動(dòng)態(tài)表單時(shí),只需簡單引入這個(gè)模塊,稍加配置即可使用。

我們希望這個(gè)模塊做好了后,在頂層使用者的角度會(huì)是這樣一個(gè)工作流程:

我們可以很容易的做出一個(gè)具有輸入屬性的組件,問題的核心在于這個(gè)組件是如何根據(jù)輸入屬性生成我們想要的表單。

也就是說,是它自己調(diào)用ComponentFactoryResolver和ViewContainerRef進(jìn)行組件的動(dòng)態(tài)生成,還是交給別人處理。

下圖是實(shí)現(xiàn)思路:

實(shí)際上我們把動(dòng)態(tài)表單拆分成了一個(gè)個(gè)小的動(dòng)態(tài)組件(不預(yù)先加載),由外層的一個(gè)組件充當(dāng)一個(gè)容器,所有的動(dòng)態(tài)組件都會(huì)在里面進(jìn)行生成和銷毀,他們共同組成了一個(gè)動(dòng)態(tài)表單。調(diào)用ComponentFactoryResolver和ViewContainerRef生成組件的的這部分邏輯沒有集成在外層容器中,而是交給了一個(gè)自定義的指令和ng-container。因?yàn)橹噶顩]有視圖,他通過注入ViewContainerRef獲取到的是宿主的視圖容器。由于ng-container不會(huì)被渲染,所以獲取到的視圖容器就是外層組件容器的視圖容器。

這么處理的好處就是不需要由外層組件統(tǒng)一對(duì)各個(gè)拆分的動(dòng)態(tài)組件進(jìn)行管理,相當(dāng)于是由動(dòng)態(tài)組件自己進(jìn)行管理。

外層組件容器大概會(huì)是下面這樣:

<form>
 <ng-container *ngFor="let config of configs" [自定義指令] >
 </ng-container>
</form>

configs是用戶的配置數(shù)據(jù),自定義指令寄宿在ng-container中,根據(jù)config渲染出各自的動(dòng)態(tài)組件,而ng-container是透明的。

看一下代碼目錄結(jié)構(gòu),最后會(huì)是這個(gè)樣子

以上就是大體的實(shí)現(xiàn)思路了,具體還有許多細(xì)節(jié)可以關(guān)注文章開頭提到的那兩篇文章,講的很詳細(xì)。

相關(guān)文章

最新評(píng)論

通州市| 横山县| 汽车| 日喀则市| 邢台市| 南阳市| 淮北市| 柳州市| 沙田区| 新和县| 景东| 许昌县| 芜湖县| 鲜城| 乌兰察布市| 德钦县| 新和县| 浦县| 绥德县| 三门峡市| 富阳市| 秀山| 山西省| 万源市| 襄樊市| 宁城县| 刚察县| 新晃| 大埔县| 蒙城县| 临潭县| 平度市| 喜德县| 英超| 土默特左旗| 尼勒克县| 皮山县| 交城县| 砀山县| 庆云县| 鹤峰县|