我們組在 retrospection 時,慢慢地有了對比。 ng-controller 做出來的東西都是大塊大塊的,彼此連動,組織很不清晰。而 directive 卻是自成體系,透過組件嵌套和通信控制,我們可以做出任意的頁面——而且還保證各個組件自己是、可測試和不受其他 Scope / EventListener 影響的。甚至,我們還總結出了一個原則:
具體呢,舉個栗子。
JavaScript
這個簡單的 html 結構,是我們吃了很多虧之后總結出來了 (高仿樣本)
你能看出什么門道?1. 組件化 2. 可視化 HTML 3. 可測試單元
1. 組件化
無需多言, bw-appnode 是一個組件,bw-table 與 bw-search 也是。這些組件彼此嵌套,也彼此,使用協議(Scope或者Service)通信。這樣的好處非常明顯。
比如我們現在還沒有做好 bw-table ,服務器 Restful API 也還沒有完成,但我們卻可以開始開發 bw-search 。bw-search 自帶的 UI 與復雜邏輯,其將對 bw-appnode 的假數據進行過濾,而 bw-table 則是渲染層而已,任何 bw-appnode 上面的變化,都會自動的 reactive 到 bw-table 里 (就是 Angular Scope 了)。
2. 可視化/具象化
緣由一:我們習慣于把很多的功能使用 JavaScript 事件綁定的方式實現。慢慢地,點擊了一個按鈕會發生什么,我們只能猜,或者辛辛苦苦的去跟蹤源代碼。而到底一個 Dom 節點上的 JavaScript 事件有幾個,我們也很難察覺——每個工程師都可能在 JS 文件的任何地方給某個節點添加上不可預期、天花亂醉的監聽事件。
緣由二:還記得為什么 HTML5 要增加那么多標簽么?比如 section/article/video。因為這樣,HTML 頁面與功能可能更加可視化,組件化。可視化是一看就知道這個是干什么的(Chrome Developer Tools Inspect、Google Crawler 精確搜索),組件化是一個標簽就渲染出自己的一套行為與 view (Web Component / Shadow-Dom的題中之義)所以,我們都近乎引頸渴望:如果從 HTML 上面就可以看出這一段 HTML 片斷/頁面塊 是干什么的,是何等的奇妙和方便啊—— 這里有另外一個術語,是描述性編程,在此也可見一斑。在我們的例子中,頂級節點有一個新的 directive,叫
JavaScript
appnode-restful
appnode-restful
顧名思義,這個就是用來拿服務端數據的。在 Server 還沒有做完時,在它里面直接拿的是靜態的數據 (使用Promise resolve),拿到數據之后,直接設在 bw-appnode 的 Scope 。
而更有意識的是,由于這個節點是的另外一個directive,我們可以在上面考慮更多復雜的邏輯,比如 ajax 數據緩存處理等。我們坦然地對這個組件說,“反正你就干這事,怎么干,你慢慢細化;想做多精,就做多精;一輩子只做一件事,就不相信你做不好。”。另外,這個節點還可以用在其他地方——要 appnode 數據的,可不止于這個 bw-appnode 頁面。不過呢,我這里不是說, Component 的主要目的是為了做重用——這個明顯不是本文要談的。
3. 可測試單元和 jsDoc
這里講的不是單元測試,而是測試單元。顯而易見,上面的任何一個 Component 都可以拿出來做測試。我們只需要引入相關的 directive 的 js 文件與 view html 文件,就可以在另外一個的測試空間,給這個 directive 做測試 (Protractor驅動)。測試用例、數據環境,想加就加,想改就改。完全不用擔心強耦合問題。
而既然是組件化, jsDoc 也好寫多了。一個 directive,一個 module 定義。
當我們把這個經驗(Everything should be directives.)總結出來之后不久幾個月,我們卻發現 Angular2 / React 的團隊早就意識到這個原則的重要性,他們早就偷偷地調整了一切。
在 React / Angular2 看來,一切都是組件。在寫一個新的 SPA 時,你首先要做的,就是把你要做的頁面劃分成不同的嵌套的組件。
借用 別人 的圖舉個栗子。
一目了然,不言而喻。不過多說一句,劃出組件之后,你還要決定是使用 Scope 通信還是使用 Publish/Subscribe 能信,另外是組織頁面(容器組件)的超級 Router 抽象層(用現成的 Router 都太弱,你應該用自己發明的 Router)。這里不再多談。
下面有幾個好資源與童鞋們共享。
最后再來一個給力的, 別人 做的東西。
后記:
我當前使用的是 Microsoft KnockoutJS,然而,從 Angular/React 得來的經驗,已經徹底的了我們的 KnockoutJS 云應用。
小方,中關村軟件園,Mar. 18, 2016。轉載請標明出處。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com