【程式碼優化】 Angular Component複用

Ray
Sep 20, 2022

--

前言

若是想要完成在A.component中打開一個B.component(popup),比較直覺的做法就是在A.html中加入B的selector,並用一個boolean控制是否打開,也就是

<!-- A.html --><app-b 
*ngIf = "openB"
>
</app-b>

想一下如果B這個元件想要有其他功能例如:自定義標題與內文、事件監聽,那這時需要的變數不只有openB,還需要加上title與content這些變數以及接收B的事件接收方法,程式碼就會像

<app-b 
*ngIf = "openB"
title = "標題"
content = "內文"
(emiter) = "getEmit($event)"
>
</app-b>

若B只單純提供給A使用的話這樣沒什麼問題,但現在有一個情境是:C、D、E、F…等更多的Component中都需要引入B這個popup元件

則用上面的方法就是在C、D、E、F…每個元件中的html寫入,並且在每個元件中的ts也加上openB、title、content、emit,這樣很容易使得程式碼變複雜。

例如:

<!-- B.html -->
<app-b
*ngIf = "openB"
title = "標題"
content = "內文"
(emiter) = "getEmit($event)"
>
</app-b>
<!-- C.html -->
<app-b
*ngIf = "openB"
title = "標題"
content = "內文"
(emiter) = "getEmit($event)"
>
</app-b>
...<!-- F.html -->
<app-b
*ngIf = "openB"
title = "標題"
content = "內文"
(emiter) = "getEmit($event)"
>
</app-b>

為使每個需要使用B的元件不再需要在各自的html中加上的tag,我們需要建立一個Service來管控這個popup元件(B.component),改成僅需注入Service並呼叫Open()這個Function取代原先的引入行為。

概念

目標:不在負責控制的元件.html中引入被控制的元件,僅使用Service完成打開與關閉的功能

方法:被控制的元件需要一個component及一個Service(也就是B.component與B.service),Service提供給負責控制的元件操作。

負責控制的元件(A.Component)

被控制的元件(B.component)

放個Btn就行了,主要只是看有沒有被Service控製出來

核心操作管道(B.service)

說明:把要被控制的元件(B.component)透過componentFactoryResolver創建出一個元件實體,接著append到畫面上

到這邊就可以完成用Service控制Component是否打開而不需要注入到當前操控的HTML中

傳入參數與監聽事件

例如想將”B元件”三字修改為傳入的參數,以及當B元件被點擊時想讓A元件取得事件觸發該如何處理?

需要在Service的Open的方法中回傳實例對象,則可以透過修改實例對象來達到傳入參數的效果,也可以透過訂閱實例對象達到取得事件觸發

確定目標是要可以傳入跟取得事件觸發後,開始對於負責控制的元件、被控制元件、被控制元件的Service進行修改。

a.component

b.component

b.service

結果

--

--

No responses yet