AngularJS 1.x 的缺點如何解決?
嘗試了AngularJS 1.x 十幾天,經驗很淺,感到AngularJS 有很多的優點,個人認為也有一個很大的缺點,從設計app的角度說,使用AngularJS,是從route開始,然後,再使用include來分割大的HTML,最後到controller局部變數的綁定和操作,使用Service來和伺服器通信。問題是其存在一個很大的缺點,當你的HTML有很多部分的時候,裡面可能存在很多組件的時候,基本上很難把一個組件拿出來獨立設計,數據和狀態分布在app代碼的各個地方,就算使用獨立的組件代碼,來試圖把組件隔離出來,也是很笨拙的在給自己的代碼做patch,無法產生高可復用的組件。
不知道各位是如何解決這個問題的?相比ReactJS,這可能是AngularJS最大的缺點所在,當狀態和數據分散在各個部分的時候,而HTML代碼在另一邊,就算是分布在一個class裡面,而維護大量的class也是一種大量重複的工作,想要寫一些組件的類庫,能夠在別的代碼中復用,就非常困難。如果實在找不到好的方法,只好轉ReactJS和Flux設計模式去了。最近嘗試了React,很好。看似我的問題說的不清楚,所以補充一下,我是這樣想的,就流程來說,必須要構建一個Controller,然後每個路由都要Controller,然後如果你的Controller之間有需要復用的部分,可能用Service之類的,但是呢,HTML可能很多了,然後既有很多類似vm.....之類的在裡面,然後邏輯可以還需要放到Service裡面,因為想共享,然後寫完,回頭再一看,如果HTML上的某一部分是一個組件的話,代碼分布在各個地方...然後,可以寫一個directive來處理HTML上的某一個組件,然後所有的控制邏輯都放在裡面么?完全取代上面的設計方法么(所謂的某個anguarjs style推薦的方法)?嘗試過,問題來了,directive的template可以引用url,也可以使用html,理想的方法是,html是編譯在組件裡面的,所以後者,然後directive裡面嵌入html就好多問題,格式,以及過濾什麼的。directive裡面可以使用controller,然後,如果把所有組件的邏輯都放到裡面,比如,取數據,呈現,操作數據等,然後一堆注入然後寫完之後再回頭一看,為什麼directive不是一個類呢?個人認為組件是比較輕,易於維護的解決方案,但是AngualrJS裡面似乎不夠好,是可以模擬的。 看起來這個問題很難說清楚,最近嘗試了Flux,發現很好的解決了這個問題,簡單的說:這個問題的實質就是,當你使用Angular 1的時候,如果數據模型是相關的,當更新一種數據模型的時候,可能需要同時更新另一種的時候,這個時候,更新的動作發生在不同的事件中,而更新的結果反應在不同的模型裡面,然後不同的View反饋了模型數據的改變。問題就是,動作,模型,View在這種關係裡面是混雜在一起的,所以一個Controller裡面可能操作了多個模型,一個模型裡面可能對應了多個View,而對於UI而言,是基於某一部分是一個組件這樣的分析,這個時候,看起來代碼到處都是。但是Flux是一種單向的基於,Dataflow programming,的設計,用Flux來寫上面的內容,所反映出來的,代碼始終都在自己所在的模塊,動作,都在Action裡面,Dispatcher來分派Action給Store,然後Store修改數據,通知View,然後View更新呈現。仔細想想這種分別,用Flux,無論怎麼寫,數據流都是流向固定的方向,而且都是明確的模塊,所以很好的解決了上面出現的問題。 AngularJS 2看起來不錯,還沒用過。1是代碼寫的越大,感覺裡面邏輯越複雜,結構越複雜,感覺就是代碼到處都是這樣。
Angular 1.x的一大問題是:沒有提供官方的最佳實踐。
關於代碼怎麼規範,有這樣一個庫:johnpapa/angular-styleguide · GitHub
很詳細,但這只是一種代碼規範,在組件規劃方面是有欠缺的。
我的觀點是:Angular官方沒有提供一些比較好的範例,對組件化的約定也很鬆散,但這是優勢而不是劣勢,這意味著,你可以把一些有公共性的東西用1.4之前版本的directive,或者1.5版本引入的components封裝起來,也可以把另外一些靈活的東西直接使用ng-include或者route的template,願意怎麼做,完全取決於業務本身和你自己。
針對你這樣的場景,我有如下建議:
先考慮業務代碼的復用性是什麼類型的。是單獨的邏輯有復用性嗎?是單獨的界面交互有復用性嗎?是數據和邏輯的整體有復用性嗎?在一個有一定規模的項目中,這些都可能存在,也都可以被用不同方式提供。- 如果單獨的邏輯有復用性,做成service
- 如果單獨的界面交互有復用性,做成directive,比如常見的一些「控制項」
- 其他一些附加功能,比如filter之類,適當提取
- 如果是帶業務特性的一塊界面,連同其邏輯,也可以做成directive,你所指的「組件」應該也包括這塊。在這裡面,還可以有一些策略,比如把這些組件也設計為多級可復用的:
- 一個controller可以被多個不同的html模板使用,展示成同一業務的不同形態。(注意這裡不要過於追求controller的復用性,能搞就搞,不能就果斷分成多個)
- 一個組件可以由可復用的controller,自身的template,依賴的service,filter之類聯合構成
因此,你說這些是Angular 1.x的缺點,……並不是。Angular 1.x的缺點只有兩點:
- 糟糕的模塊機制,包括不必要的依賴注入
- 臟檢查以及作用域繼承機制(不完全是缺點)
你說的不是angular的缺點。狀態管理的混亂是自己的問題呀
有句話我看不懂用include分割大html,既然是route開始的話,template裡面就是每一個路由對應的模板,可能我沒用過你所說的include吧,還有不能在每個模板裡面復用組件,那就是app設計的問題,directive無非就是另一種手段控制dom和生成標籤給你用,你找不到統一的方法來寫組件,那換其他框架也是如此啊
說實在沒有完全理解題主的問題描述,但從大意看來,估計是題主對 Angular 的了解還不全面,尚未找到合理的工程代碼組織範式,誤認為是 Angular 的「缺點」所致。
題主原提問「AngularJS 1.x 的缺點如何解決?」,但問題並不出在 Angular 身上,建議對問題題干做修改。一、代碼散落在各處的問題我自己習慣使用 ui-router 做 view 管理,直接看代碼示例應該就能 get 我的點了:var app = angular.module("myApp", []);
// $stateProvider 是 ui-router 的頁面(ui-router 稱為 "state") 定義介面
app.config(function ($stateProvider) {
$stateProvider.state("exampleState", {
url: "example",
template: """
&
Example State&
&{{data}}&
""",
resolve: {
preloadData: function ($http) {
return $http.get("/data").then(function (data) {
return data;
});
}
},
controller: function ($scope, preloadData) {
$scope.data = preloadData;
}
})
});
如上,一個 view 裡頭相關的 html, controller, service (建議只在此處定義該頁專有的部分 service) 集結於一處,即可解決你認為代碼散落在各處的弊端了。
ui-router 支持多級 state 嵌套,parent-child states scope 繼承,因此分割大片 html 的任務也沒問題。
二、組件抽離的問題
可以將組件用 directive 來定義。只要你願意,自定義 directive 完全可以做到擁有自己的隔離域 (isolated scope),脫離對外部代碼的依賴,而只留出乾淨的介面去和外部進行通訊。不過 directive 內容太多了,在這裡我就不舉例說了,還請自行細讀文檔吧。送題主一個傳送門:AngularJS推薦閱讀:
※angular 自定義指令如何操作DOM的問題?
※新手,覺得Angularjs好難,該如何學習Angularjs?
※Handlebars 和angularjs有什麼區別?分別在什麼情況下使用?
※react.js,angular.js,vue.js學習哪個好?
※請問 React 和 Angular 各有什麼優缺點,各自又適合什麼開發場景?
TAG:AngularJS |