摘要:組件組件是新提出的,是一種特殊的指令,的源碼中也彰顯了這一點(diǎn)。
說(shuō)到關(guān)于 Angular Styleguide,很多人可能會(huì)想到這篇經(jīng)典的文章。的確,它是一篇非常棒的文章,甚至已經(jīng)被翻譯成許多種語(yǔ)言(包括中文),在 github 上更是擁有將近 1.9w 個(gè) star。
然而,這次談?wù)摰牟皇撬R驗(yàn)殡S著 ES6 的廣泛應(yīng)用,以及 Angular 1.5 的發(fā)布,它有那么一點(diǎn)點(diǎn)不夠時(shí)髦(也談不上過(guò)時(shí)哈~)。
本文的大部分觀點(diǎn)都來(lái)自這篇文章(以下簡(jiǎn)稱原文),但個(gè)人根據(jù)工作上積累的一些經(jīng)驗(yàn)添并不是完全認(rèn)同原文的所有想法,并想去除些繁冗的例子,于是就沒(méi)有直接翻譯原文。
言歸正傳,下面就來(lái)看看使用 ES6 來(lái)編寫(xiě)基于 Angular 1.5 的代碼有哪些最佳實(shí)踐。
模塊架構(gòu)在 Angular 體系中,所有代碼都是基于模塊的,它來(lái)封裝模塊內(nèi)部的邏輯、模板、路由和子模塊。
模塊劃分原文將模塊分為 3 大類,分別是:root, component 和 common,并創(chuàng)建相應(yīng)的文件夾來(lái)儲(chǔ)存。
root:根模塊組件,用來(lái)啟動(dòng)應(yīng)用和相應(yīng)模板
component:包含所有可重用的模塊,模塊中可以包含 components, controllers, services, directives, filters and tests
common:包含所有業(yè)務(wù)的模塊(即不可重用,和 component 最大的區(qū)別),它可以是頁(yè)面布局、導(dǎo)航和頁(yè)腳等等。
原文中有詳細(xì)的例子,但就如文章開(kāi)頭所說(shuō),在這里就不貼了。
但是,我并不完全認(rèn)同原文觀點(diǎn)。
因?yàn)椋琧ommon 的翻譯是公共的,在 common 中存放業(yè)務(wù)代碼也和我們一直以來(lái)的做法相悖;其次是,在 Angular 的開(kāi)發(fā)過(guò)程中,還是存在一些可以在業(yè)務(wù)邏輯中公用的代碼,比如 service 和 filter。所以,我更傾向于將它分為 4 部分,分別是 root, app, component 和 common。
root:和原文的作法一樣,依舊是用來(lái)啟動(dòng)應(yīng)用,并包含了應(yīng)用的模板(并不一定要一個(gè)文件夾,可以是根目錄下的一個(gè) app.js 文件)
app:類似于之前的 common 模塊,包含所有的業(yè)務(wù)模塊組件
component:同原文的一樣,包含所有可重用的模塊組件
common:公用代碼模塊,包含可公用的代碼,如 service 和 filter
模塊導(dǎo)出使用 ES6 肯定會(huì)使用強(qiáng)大的模塊語(yǔ)法,在同 Angular 一同使用時(shí),一定要注意導(dǎo)出的是模塊的名字,而非是 Angular 的模塊對(duì)象,這樣才能再另一處被其他模塊注入。
// 精簡(jiǎn)了原文的代碼,去除了一些和這節(jié)無(wú)關(guān)的代碼 import angular from "angular"; import CalendarComponent from "./calendar.component"; const calendar = angular .module("calendar", []) .component("calendar", CalendarComponent) .name; export default calendar;文件命名
首先,為每個(gè)模塊添加 index.js 文件來(lái)定義整個(gè)模塊,這樣再別的模塊中可以通過(guò)文件夾直接引入。
原文使用模塊名.文件內(nèi)容.文件類型的方式來(lái)命名一個(gè)文件,如 calendar.controller.js 等。
我完全同意第一個(gè)觀點(diǎn),但第二個(gè)中的模塊名就沒(méi)有添加的必要,因?yàn)槲募A名已經(jīng)很好的體現(xiàn)了模塊名這個(gè)含義。
組件(Component)組件是 Angular 1.5 新提出的,是一種特殊的指令,Augular 的源碼中也彰顯了這一點(diǎn)。
它相比指令更多的是數(shù)據(jù)的單向綁定和生命周期鉤子,盡管我認(rèn)為所謂的生命周期鉤子只是語(yǔ)法糖,甚至組件它本身就是個(gè)語(yǔ)法糖,但這不妨礙它成為 Angular 體系中重要的一部分。因?yàn)椋耐瞥雒鞔_的區(qū)分了指令和組件,解決了原先指令劃分不清、承擔(dān)過(guò)多工作的問(wèn)題。
組件屬性Property | Support |
---|---|
bindings | Yes, 只使用 @, <, &,避免使用 = |
controller | Yes |
controllerAs | Yes, 默認(rèn)為 $ctrl |
require | Yes |
template | Yes |
templateUrl | Yes |
transclude | Yes |
控制器只應(yīng)在組件中使用,如果你只想創(chuàng)建一個(gè)控制器,那你應(yīng)創(chuàng)建一個(gè)無(wú)狀態(tài)組件來(lái)管理它。
使用 class 關(guān)鍵字來(lái)創(chuàng)建控制器時(shí)要注意以下幾點(diǎn):
使用 constructor 處理依賴注入
之前提到過(guò),導(dǎo)出模型名,而并不是直接導(dǎo)出模型
使用箭頭函數(shù)
使用 $onInit, $onChanges, $postLink 和 $onDestroy 生命周期
(注意:$onChanges 會(huì)在 $onInit之前被調(diào)用)
使用默認(rèn)的控制器 $ctrl,不使用 controllerAs 修改控制器的別名
單向數(shù)據(jù)流總是使用 < 單向數(shù)據(jù)綁定來(lái)代替 = 雙向數(shù)據(jù)綁定
使用 $onChanges 來(lái)監(jiān)聽(tīng)數(shù)據(jù)的變化
父組件的方法使用 $event 作為參數(shù)傳遞的名字
子組件調(diào)用時(shí)返回一個(gè)包含有 $event 屬性的對(duì)象
這是不是看上去很像 Redux?沒(méi)錯(cuò),原文的作者也是推薦使用 Angular Redux 來(lái)管理狀態(tài)。
狀態(tài)組件(Stateful components)和無(wú)狀態(tài)組件(Stateless components)狀態(tài)組件和無(wú)狀態(tài)組件其實(shí)分別對(duì)應(yīng)了 Redux 中的容器組件(Smart/Container Components)和展示組件(Dumb/Presentational Components),這部分原作者主要也是表達(dá)了在 Angular 中實(shí)現(xiàn)單向數(shù)據(jù)流的理念,但原作者提供的例子并不是完整的 Redux,它沒(méi)有單一的 Store 和 Reducer。
指令(Directive)相信指令大家都很熟悉了,但自從 Angular 1.5 提供了組件,指令的選擇就應(yīng)當(dāng)慎重考慮,它應(yīng)當(dāng)只在裝飾 DOM 時(shí)使用。
不使用 template, templateUrl, scope, bindToController 或 controller 等相關(guān)的屬性,如果想用,考慮是不是它可以用 component 來(lái)實(shí)現(xiàn)
總是使用 restrict: "A"
指令屬性Property | 是否使用 | Why |
---|---|---|
bindToController | No | 使用組件替代 |
compile | Yes | DOM 操作/事件的預(yù)處理 |
controller | No | 使用組件替代 |
controllerAs | No | 使用組件替代 |
link functions | Yes | DOM 操作/事件的處理 |
multiElement | Yes | See docs |
priority | Yes | See docs |
require | No | 使用組件替代 |
restrict | Yes | 總是使用 restrict: "A" |
scope | No | 使用組件替代 |
template | No | 使用組件替代 |
templateNamespace | Yes (如果必須) | See docs |
templateUrl | No | 使用組件替代 |
transclude | No | 使用組件替代 |
服務(wù)主要用于封裝一些不應(yīng)在組件中處理的業(yè)務(wù)邏輯和請(qǐng)求。
Angular 提供 2 種創(chuàng)建服務(wù)的方式 service 和 factory。在 ES6 引入了 class 關(guān)鍵字后,它能非常友好地同 service一起工作,所以,無(wú)論何時(shí)都使用 service 來(lái)創(chuàng)建服務(wù)。
類 or 方法原文的標(biāo)題是常量或類(Constants or Classes),容許我自作主張的修改一下標(biāo)題,因?yàn)槲艺J(rèn)為原文的實(shí)現(xiàn)的區(qū)別更主要的在于是使用類或方法去定義一個(gè)服務(wù)或控制器等。
當(dāng)然這兩種方法都可以,因?yàn)轭愃旧砭褪欠椒ǖ囊粋€(gè)語(yǔ)法糖。但是,Angular 2 是重度依賴 class 關(guān)鍵字的,所以,我認(rèn)為還是全部統(tǒng)一使用 class 關(guān)鍵字來(lái)聲明服務(wù)、控制器、過(guò)濾器、指令和組件的定義等。
值得注意的是,Angular 組件和指令定義的參數(shù)是一個(gè)對(duì)象,所以在使用 class 定義時(shí),要手動(dòng)實(shí)例化它。
工具最后,原文作者還推薦了一些工具
Babel:編譯工具,這就不多說(shuō)了,必備神器
TypeScript:還是為了 A2
Webpack:打包工具,用過(guò)都說(shuō)好
ngAnnotate:自動(dòng)依賴注入,和打包工具一起服用效果更好
Angular Redux:狀態(tài)管理
以上為個(gè)人觀點(diǎn),歡迎交流。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/79787.html
摘要:他們即不是指令,也不應(yīng)該使用組件代替指令,除非你正在用控制器升級(jí)模板指令,組件還包含數(shù)據(jù)事件的輸入與輸出,生命周期鉤子和使用單向數(shù)據(jù)流以及從父組件上獲取數(shù)據(jù)的事件對(duì)象。 showImg(https://segmentfault.com/img/bVynsJ); 關(guān)鍵詞 架構(gòu), 文件結(jié)構(gòu), 組件, 單向數(shù)據(jù)流以及最佳實(shí)踐 來(lái)自 @toddmotto 團(tuán)隊(duì)的編碼指南 Angular 的編碼...
摘要:是文檔的一種表示結(jié)構(gòu)。這些任務(wù)大部分都是基于它。這個(gè)實(shí)踐的重點(diǎn)是把你在前端練級(jí)攻略第部分中學(xué)到的一些東西和結(jié)合起來(lái)。一旦你進(jìn)入框架部分,你將更好地理解并使用它們。到目前為止,你一直在使用進(jìn)行操作。它是在前端系統(tǒng)像今天這樣復(fù)雜之前編寫(xiě)的。 本文是 前端練級(jí)攻略 第二部分,第一部分請(qǐng)看下面: 前端練級(jí)攻略(第一部分) 在第二部分,我們將重點(diǎn)學(xué)習(xí) JavaScript 作為一種獨(dú)立的語(yǔ)言,如...
摘要:由于系統(tǒng)變得越來(lái)越復(fù)雜,人們提出了稱為預(yù)處理器和后處理器的工具來(lái)管理復(fù)雜性。后處理器在由預(yù)處理器手寫(xiě)或編譯后對(duì)應(yīng)用更改。我之前建議的文章,,也涵蓋了預(yù)處理器相關(guān)的知識(shí)。 譯者:前端小智 原文:medium.freecodecamp.org/from-zero-t… medium.freecodecamp.org/from-zero-t… 我記得我剛開(kāi)始學(xué)習(xí)前端開(kāi)發(fā)的時(shí)候。我看到了很多文章及...
摘要:一般來(lái)說(shuō),聲明式編程關(guān)注于發(fā)生了啥,而命令式則同時(shí)關(guān)注與咋發(fā)生的。聲明式編程可以較好地解決這個(gè)問(wèn)題,剛才提到的比較麻煩的元素選擇這個(gè)動(dòng)作可以交托給框架或者庫(kù)區(qū)處理,這樣就能讓開(kāi)發(fā)者專注于發(fā)生了啥,這里推薦一波與。 本文翻譯自FreeCodeCamp的from-zero-to-front-end-hero-part。 繼續(xù)譯者的廢話,這篇文章是前端攻略-從路人甲到英雄無(wú)敵的下半部分,在...
摘要:參照組件單一職責(zé),單個(gè)模塊文件僅承擔(dān)有限職責(zé),。路由聲明與組件聲明在統(tǒng)一文件內(nèi)部聲明。組件替換約定服務(wù)在內(nèi)部屬于單例,實(shí)例聲明通過(guò)的方式,聲明服務(wù)。指令熱替換同樣采用較為粗放的容器定位策略,通過(guò)路由模板替換實(shí)現(xiàn)。 ng-hot-loader 前言 webpack-dev-server自帶支持模塊熱替換特性(HMR),不刷新頁(yè)面實(shí)現(xiàn)代碼局部更新,使用HMR可以大幅提升開(kāi)發(fā)效率。 實(shí)現(xiàn)目標(biāo)...
閱讀 2348·2021-11-15 11:37
閱讀 2625·2021-09-23 11:21
閱讀 2952·2021-09-07 10:11
閱讀 3164·2019-08-30 15:53
閱讀 2826·2019-08-29 15:13
閱讀 1606·2019-08-26 13:57
閱讀 1098·2019-08-26 12:23
閱讀 2438·2019-08-26 11:51