摘要:原文的第四篇文章中的一個重要元素在上一篇文章中沒有涉及,使用高階組件中的常用模式可以將組件中的公用邏輯分離出來。同時,因?yàn)榻M件的模板并不存在任何的變動,我們可以將它轉(zhuǎn)化為一個指令,這樣我們可以以更加靈活的方式來使用它。
03-b Enhance Components with Directives
原文: Enhance Components with Directives
Kent C. Dodds的第四篇文章中的一個重要元素在上一篇文章中沒有涉及,使用withToggle高階組件(HoC, react中的常用模式)可以將
雖然上一篇文章中上面提及的三個組件并沒有太多的公用邏輯,可以萬一它們有公用邏輯呢?如果我們想要提供更加聲明式的功能,比如能夠顯式的聲明它們使用的
同時,因?yàn)?b>
允許我們的
允許通過withToggle`指令顯式地設(shè)置`
將
@Directive({ exportAs: "toggle", selector: "toggle, [toggle]", }) export class ToggleDirective {}
你可能注意到了,指令的選擇器允許toggle指令可以以標(biāo)簽名和屬性名的形式來使用。對于exportAs關(guān)鍵字是必須要提供的,因?yàn)檫@是當(dāng)我們需要在別的指令或者組件能夠獲取toggle指令引用的名字,會在這個系列文章的第5章詳細(xì)刪除exportAs(Handle Template Reference Variables with Directives)。
2)withToggle指令在這個新的指令中,我們將會封裝關(guān)于如何選取需要綁定某個toggle指令實(shí)例的邏輯。
首先,我們的設(shè)想是這樣的,每一個組件注入withToggle指令,而不是直接注入最鄰近的父toggle指令。同時每個使用withToggle指令的組件通過使用withToggle.toggle來訪問它所綁定的toggle指令的實(shí)例,如下:
@Component({ selector: "toggle-off", template: ``, }) export class ToggleOffComponent { constructor(public withToggle: WithToggleDirective) {} }
其次,withToggle指令將它自身與toggle指令的選擇器綁定(就是兩個指令的選擇器是相同的),同時增加一個額外的選擇器[withToggle],如下:
@Directive({ exportAs: "withToggle", selector: "toggle, [toggle], [withToggle]", }) export class WithToggleDirective //...
現(xiàn)在withToggle指令為它的子組件們提供所綁定的toggle指令實(shí)例,無論這個實(shí)例是顯示綁定的,還是默認(rèn)的父toggle指令。關(guān)于其中實(shí)現(xiàn)的具體細(xì)節(jié),可以參考文章最后的附錄部分。
成果我們的app.component.html現(xiàn)在可以通過三種不同的使用方式來展現(xiàn)內(nèi)容。
1)基本......
注意#firstToggle和#secondToggle視圖變量是如何使用toggle組件的,前者使用屬性聲明的方式,后者使用標(biāo)簽名聲明方式,無論怎樣,它們都按理想中那樣運(yùn)行。
而且,#secondToggle是嵌套在#firstToggle中的,所以它的子組件使用的是它本身的開關(guān)狀態(tài),而非#firstToggle中的,這符合我們的預(yù)期。
2)顯式引用First:
On Off
這里沒有任何toggle指令是當(dāng)前p標(biāo)簽的子組件的祖先,但是通過withToggle指令,我們可以讓所有的子組件使用#firstToggle的toggle指令實(shí)例。
3)自定義組件withToggle指令甚至可以通過DI機(jī)制注入到內(nèi)部的任何自定義組件中,如
withToggle的實(shí)現(xiàn),是一個標(biāo)準(zhǔn)的指令聲明方式,除了它的構(gòu)造方法,如下:
constructor( @Host() @Optional() private toggleDirective: ToggleDirective, ) {}
值得注意的有兩點(diǎn):
@Host():這個裝飾器的作用是,可以限制從屬于當(dāng)前指令的DI注入器,僅注入綁定到某個滿足特定條件指定或者組件上的toggle指令實(shí)例,而不是從它的祖先組件們中注入。(這里選擇器為空,則為宿主對象)
@Optional():這個裝飾器會告訴編譯器,當(dāng)注入器沒有找到任何可注入的toggle指令時,不要拋出錯誤(如果我們手動的指定某個引用),這樣在它無法被注入時,使它保持undefined即可。
現(xiàn)在我們可以很容易的理解在ngOnChanges生命周期鉤子函數(shù)中的代碼的作用,
this.toggle = this.withToggle || this.toggleDirective;
如果我們的@Input()被指定,那么使用它的值
如果沒有,則嘗試去使用在當(dāng)前宿主對象上注入的toggle指令實(shí)例
如果沒有,則使用undefined
當(dāng)前的this指定withToggle本身,所以擁有它引用的子組件都可以訪問它。
在線代碼演示(自備梯子): https://stackblitz.com/edit/a...
譯者注在這一節(jié)中,主要進(jìn)行了以下幾方面的改進(jìn):
簡化toggle本身,因?yàn)樗恢笔亲鳛橐粋€容器組件使用的,所以完全可以以指令(可以理解為沒有模板的組件)的形式存在
依賴注入(DI)的機(jī)制雖然很強(qiáng)大,但是受限于它的運(yùn)作原理(關(guān)于具體的運(yùn)作原理可以參考官方文檔)。這里原作者使用一個額外的withToggle指令作為中間件,來作為toggle指令的托管容器。這部分理解起來可能需要先了解一下視圖變量和exportAs的相關(guān)的知識
對于toggle指令實(shí)例的獲取邏輯,采用平穩(wěn)退化的策略,就好比人在實(shí)際生活中思考問題的方式一樣。
這種開發(fā)模式,在實(shí)際工作中,我有一次在重構(gòu)公司項(xiàng)目中一個關(guān)于表單組件的過程中曾使用過,之所以使用這種方式,是因?yàn)樵诒韱谓M件中,會存在一些關(guān)于聯(lián)動校驗(yàn)或者分組的需求,如果將這部門邏輯封裝為service或者直接寫在controller內(nèi)部,越到后面會發(fā)現(xiàn)邏輯復(fù)雜度越高,從而越來越難維護(hù)。
使用這種模式,將復(fù)雜的邏輯劃分成小的顆粒,再封裝為獨(dú)立的指令,在需要用到這些邏輯的組件中注入這些指令即可,指令的特點(diǎn)就是一般都會比較簡潔,只會做一些簡單的事情,相比之下,維護(hù)一個十分復(fù)雜的service和維護(hù)若干簡單的指令,我更傾向于后者。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90803.html
摘要:為了適應(yīng)表單校驗(yàn)的靈活性,我們使用這種模式會事半功倍,提供校驗(yàn)信息的組件僅僅聲明渲染表單錯誤提示信息需要設(shè)計(jì)的狀態(tài)變量即可,比如等等,對于錯誤信息的文案及樣式,統(tǒng)統(tǒng)交由錯誤提示組件的使用者完成。 06 Use Render Props最近在React社區(qū)中引起了轟動,但是與之類似的模式在Angular中似乎并沒有得到太多關(guān)注。我在之前寫的文章提及過,TemplateRefs就是Ang...
摘要:原文如那樣,我們將使用一個相對簡單的組件來說明這些模式。組件的職責(zé)是僅僅是管理一個簡單的布爾值狀態(tài)屬性。文件夾并且特別是,將針對庫在不同的情形下的使用做出相應(yīng)的改變。 寫在前頭 Angular到現(xiàn)在已經(jīng)到5.x的版本了,對于MVVM框架我首先接觸的是angularjs后來又轉(zhuǎn)為react,之后換了工作因項(xiàng)目技術(shù)棧的原因又轉(zhuǎn)換到之前的angularjs,在實(shí)際工作中實(shí)施了公司幾個比較重要...
摘要:目標(biāo)提供一些方法或指令給組件使用者,使其可以與所提供的元素交互并修改它們。這個指令擁有一個屬性并與組件共享,該屬性將決定屬性的值是還是。 07 使用 Content Directives 原文: Use Content Directives 因?yàn)楦附M件會提供所有相關(guān)的 UI 元素(比如這里的 button),所以 toggle 組件的開發(fā)者可能無法滿足組件使用者的一些附加需求,比如,...
摘要:同時,依賴注入機(jī)制是依附于組件本身存在的,并不依附于模板的層級關(guān)系,因此不會面臨問題二的困擾。對于木偶組件本身,往往作為消費(fèi)者存在,這種情況下使用機(jī)制可能會達(dá)到更好的效果。 03-a Communicate Between Components Using Dependency Injection 原文: Communicate Between Components Using Dep...
摘要:相關(guān)話題裝飾器將會返回在組件標(biāo)簽包含的內(nèi)容中,第一個符合選擇器的子組件或者子指令的引用,比如。或者裝飾器是用來獲取在組件內(nèi)部模板中使用的單個或者多個組件的。 02 Write Compound Components 原文: Write Compound Components 目標(biāo) 我們需要實(shí)現(xiàn)的需求是能夠使使用者通過組件動態(tài)的改變包含在它內(nèi)部的內(nèi)容。 實(shí)現(xiàn) 我們可以把toggle抽象...
閱讀 2818·2021-10-26 09:48
閱讀 1684·2021-09-22 15:22
閱讀 4063·2021-09-22 15:05
閱讀 621·2021-09-06 15:02
閱讀 2612·2019-08-30 15:52
閱讀 2118·2019-08-29 18:38
閱讀 2763·2019-08-28 18:05
閱讀 2336·2019-08-26 13:55