AngularJS 有沒有缺點?MVVM 框架中有比它更好的嗎?

之前鐘意backbone,但慢慢感覺不夠強大。。所以轉向AngularJS。

想問下: AngularJS有木有缺點?MVVM框架中有比它更好的嗎?

另外AngularJS中可以使用 Handlebars嗎? 我不想因為換了MVC框架,導致以前的Html模版又要重寫。。


最近積攢過十幾天經驗,已經喜歡上了 AngularJS 。

AngularJS 自集成了模板,不能使用第三方的——不過你仍然可以 Jade 之類的模板進行預編譯,以簡化書寫。

與一些 MDV 同類相比(Facebook 有 React;Google 另外還有 Dart、Polymer;Mozilla 有 X-Tag),我認為 AngularJS 勝在可用和易於測試這兩方面。

如下是幾個算是缺點的地方:

directive

- 過於複雜,上手比較難,看看這些符號和函數就能理解複雜度都多高:

@、=、
^、?
E、A、C、M
$observe/$watch
compile/prelink/postlink

- 始終要佔用一個元素,尤其是當只想輸出文本節點,而同時又必須使用 ng-switch 或 ng-repeat 時。

集成

- 第三方庫一起使用有點不便——比如和 DOM 相關的庫,需要手動包裝成 directive;和 Closure Library 集成,很早有計劃改進,但還沒有什麼變化;

- angular 相關的開源組件也還不夠豐富 —— 除了 angular-ui 提供了一些,另外 angular-component-spec 可能對這點會有幫助;

$resource 功能稍弱

缺少很多必要的 HTTP 方法,需要自定義;缺少全局配置;內部 $http 的 PATCH 方法對低版 IE 不兼容;

相關工具

yeoman/generator-angular 還不夠完善,還有一些 bug:

- usemin 還不支持多個目錄查找、不能處理條件注釋的情況;

- CoffeeScript 和 JavaScript 混用時不太搭,需要一些 hack;

- livereload 在文件擴展名不是 .html 時也稍微有點問題,需要 hack;

debug 麻煩

AngularJS 給出的調用鏈又深、又難理解。

另外還有兩個可以注意的舊版本問題,最近新版本已經解決(還沒發布到 bower):

- $resource 對 promise 的支持;

- directive 對動畫的支持;


我們的團隊很有趣,最近我們又有個新服務要開發,大家紛紛覺得,angular很好,但都不想用。。。

為什麼不想用呢,大概有幾個原因:

  1. 源碼太重了,有啥問題想自己干點猥瑣事情的時候,很難分析和入手
  2. 架構太重了,干點屁事架子一大堆。(當然,這個其實從某種意義上講是angular的優點,為何呢,因為angular其實本質上是將後端的開發模型引入到了前端,因此呢,前端工程師可能會覺得太麻煩,後端工程師呢,就算覺得麻煩,但是理解起來很輕鬆,所以上手很快,跟在服務端寫java沒啥區別嘛。)
  3. 綁定複雜的UI設計的時候,還是有些麻煩。這個很多人都提到過,directive相當複雜,我們做完一個項目都沒人願意去寫directive,寧願自己寫jquery。很多人提到jquery直接操作dom是個坑,這個我完全同意,但是對我們卻不是問題,因為我們的團隊里的人相對來說對這些東西的關係相當清楚和熟練(事實上,我很久以前曾經在其他項目中實現過一個mini的類angluar框架,當然,那個不通用,也沒法開源,但因此對angular的內部實現思路我可以說非常清楚,不用讀代碼我都知道他會怎麼做,他能怎麼做,那些坑我可都是一個一個填過來的),可以自由的在angular和jquery之間進出,因此對我們來說,寫jquery比寫directive方便。
  4. 跟第三點也多少有些關聯,就是我們希望有更「方便」的綁定的聲明方式。話題稍微延伸一下,我們公司有一個自己的後端框架Asta4D,它實現了一個數據綁定和模板完全分離的模型,也就是說,我們的html裡面(幾乎)不會嵌入框架的任何動態聲明,數據綁定的聲明完全在Java代碼端完成,這種模型對不但對設計非常友好,而且對後端開發人員也很友好,因為無論設計人員給出如何複雜炫酷的HTML,我們的後端人員都不需要去碰一個指頭,都在自己的Java代碼裡面就能夠完成綁定聲明了。尤其是在頁面有重構發生的時候,設計人員重構完的頁面,在理想的情況下,我們可以無須修改數據綁定的聲明,事實上,這是大多數的情況。因此,話說回來,我們的團隊在習慣了這種開發模式後,對於嵌入到HTML中的數據綁定聲明,有一種天然的厭噁心理,因為大多數時候設計人員修改了頁面之後,開發人員都要介入修復被破壞的數據綁定。

延伸話題兼廣告預告:

我們這次的新服務很有趣,大家紛紛表示這個需求沒法做服務端渲染,還是rich client的幹活吧,那JS用啥呢,頭次用angular不錯呀,但有沒有其他選擇啊。。。然後我們評估了一堆框架,最後的結論呢,react看上去很不錯啊,但是。。。那個js和html混合書寫的風格。。。哎呀,還是算了吧。。。再然後,就是一堆angluar like的框架,大家看了半天,哎呀,既然都是angular like的,那還費那個勁干毛呀,就用angular唄,雖然有些不爽,但至少不用重新學習了,多省事啊。

這事兒還沒完,上周三快下班的時候,我突然手賤,把我們的服務端框架的綁定代碼,改寫成js了,服務端綁定用的名字是render,我這客戶端做雙向綁定了嘛,我把名字改成了bind,然後share給大家看了一下,大家突然就雞凍了啊,哎呀,這個好啊,這樣都不用學了嘛,直接就上手寫了。

我說,哥幾個別雞凍,這個寫法吧,js實現不了的。。。。

然後,我又擼了擼,寫了個變種的寫法,又給大家看了看,這個寫法js應該能實現了,但是沒有我們後端那種寫法那麼直觀了,大家看了之後,紛紛表示,不錯不錯,只要能把綁定從html裡面抽出來,就很不錯了,而且也不算太難懂,跟我們的後端代碼其實思路還是一致的嘛,只是語法上稍微有點變化而已,沒事沒事,就這玩意兒吧?豬啊,你幾天能擼出來?

我擦,我們這個服務預定是五一前上線吧?哥幾個下周就準備開始堆代碼了吧?你們讓我現在開始擼框架?哥幾個紛紛表示,沒事沒事,萬一沒擼好,有問題的地方我們就用jquery硬幹就是了,你先擼著,我們先寫著。好吧,我被打敗了,答應他們兩周內給一個帶bug的預覽版出來讓他們先用上。。。

============= 5.20 更新================

已經open了:

astamuse/asta4js · GitHub


目前來看是最好的,功能多 3D的特性基本傲視群雄,從flex借鑒的數據綁定,指令很容易上手擴展html標籤,再加上依賴注入 是一個集大成的框架。對比backbone只提供了router mv 功能較少,backbone更多是一個幫助代碼結構的框架,具體功能基本沒有.

anggular無法使用handlebar,因為不是字元串模版

Angular的缺點其實不多.

1 angular 入門很容易 但深入後概念很多, 學習中較難理解.

2 文檔例子非常少, 官方的文檔基本只寫了api, 一個例子都沒有, 很多時候具體怎麼用都是google來的, 或直接問misko,angular的作者.

3 對IE6/7 兼容不算特別好, 就是可以用jQuery自己手寫代碼解決一些.

4 指令的應用的最佳實踐教程少, angular其實很靈活, 如果不看一些作者的使用原則,很容易寫出 四不像的代碼, 例如js中還是像jQuery的思想有很多dom操作.

5 DI 依賴注入 如果代碼壓縮需要顯示聲明.


可以試一下我的avalon。文檔齊全,示例上百,入手容易,體積少,已經有幾個成功案例了

現在邊鋒,搜狐,百度無線,去哪邊網,金山都在用了

  • 移動應用:讀酷
  • chrome插件:飯否客戶端
  • 為知筆記
  • 基於python的網面示例
  • 企業級應用:超博CRM客戶關係管理系統(帳號:crm_ceo 密碼:nncb_ceo)
  • avalon+jQuery實現域名註冊查詢
  • 路由器示例

=====================================

  • 使用簡單,在HTML中添加綁定,在JS中用avalon.define定義ViewModel,再調用avalon.scan方法,它就能動了!
  • 兼容到IE6(其他mvvm框架, knockoutjs IE6, angularjs IE8, emberjs IE8, winJS IE9 ),另有avalon.mobile,它可以更高效地運行於IE10等新版本瀏覽器中
  • 沒有任何依賴,不到4000行,壓縮後不到50KB
  • 支持管道符風格的過濾函數,方便格式化輸出
  • 局部刷新的顆粒度已細化到一個文本節點,特性節點
  • 要操作的節點,在第一次掃描就與視圖刷新函數相綁定,並緩存起來,因此沒有選擇器出場的餘地。
  • 讓DOM操作的代碼近乎絕跡
  • 使用類似CSS的重疊覆蓋機制,讓各個ViewModel分區交替地渲染頁面
  • 節點移除時,智能卸載對應的視圖刷新函數,節約內存
  • 操作數據即操作DOM,對ViewModel的操作都會同步到View與Model去。
  • 自帶AMD模塊載入器,省得與其他載入器進行整合。
  • 強大的UI庫,有專業的拿高薪的團隊在維護與升級 oniui

相關學習教程:《入門教程》→迷你易用的MVVM框架→ HTML5交流會有關avalon的PPT→《avalon最佳實踐》


正好今天回答了 說說AngularJS在實際應用中的的優缺點?的問題,複製過來供參考

Angular.js 優點:

1. 模板功能強大豐富,並且是聲明式的,自帶了豐富的Angular指令;

2. 是一個比較完善的前端MVC框架,包含模板,數據雙向綁定,路由,模塊化,服務,依賴注入等所有功能;

3. 自定義Directive,比JQuery插件還靈活,但是需要深入了解Directive的一些特性,簡單的封裝容易,複雜一點官方沒有提供詳細的介紹文檔,我們可以通過閱讀源代碼來找到某些我們需要的東西,如:在directive使用 $parse;

4. ng模塊化比較大膽的引入了Java的一些東西(依賴注入),能夠很容易的寫出可復用的代碼,對於敏捷開發的團隊來說非常有幫助,我們的產品 Worktile 讓工作更簡單 從上線到目前,UI變化很大,在摸索中迭代產品,但是js的代碼基本上很少改動。

缺點:

1. 驗證功能錯誤信息顯示比較薄弱,需要寫很多模板標籤,沒有JQuery Validate方便,所以我們自己封裝了驗證的錯誤信息提示,詳細參考 why520crazy/w5c-validator-angular · GitHub ;

2. ngView只能有一個,不能嵌套多個視圖,雖然有 angular-ui/ui-router · GitHub 解決,但是貌似ui-router 對於URL的控制不是很靈活,必須是嵌套式的(也許我沒有深入了解或者新版本有改進);

3. 對於特別複雜的應用場景,貌似性能有點問題,特別是在Windows下使用chrome瀏覽器,不知道是內存泄漏了還是什麼其他問題,沒有找到好的解決方案,奇怪的是在IE10下反而很快,對此還在觀察中;

4. 這次從1.0.X升級到1.2.X,貌似有比較大的調整,沒有完美兼容低版本,升級之後可能會導致一個兼容性的BUG,具體詳細信息參考官方文檔 AngularJS ,對應的中文版本:AngularJS

5. ng提倡在控制器裡面不要有操作DOM的代碼,對於一些JQuery 插件的使用,如果想不破壞代碼的整潔性,需要寫一些directive去封裝一下JQ插件,但是現在有很多插件的版本已經支持Angular了,如:jQuery File Upload Demo

6. Angular 太笨重了,沒有讓用戶選擇一個輕量級的版本,當然1.2.X後,Angular也在做一些更改,比如把route,animate等模塊獨立出去,讓用戶自己去選擇。


angular的生態很好,google有全職的一個team在維護core,社區也足夠強大,網上的tutorial和資料一應俱全,總的來說社區很健康。

學習曲線頗抖,directive上手容易,想要用深比較花功夫。

dirty-check看起來很美,只是坑略多,有時候data-binding 不一定想你想的那樣work,關鍵詞$scope.apply,$scope.digest

performance issue 怎麼說還是繞不過 不過問題不大


任何一個工具的好壞需要看應用場合。我們正在搭建一個模塊化非常強的內部用web平台,完全模塊化開發,各種模板混用、js/coffee混用、css/less混用都支持。

模塊化依賴angular本身特性,這是angular的強項,服務、UI組件、業務UI可以劃分得很清晰,這個平台跨了兩年兩個項目,不斷完善,angularjs越用越爽。在這之前試過很多其它框架,jmvc、sproutcore、ember、backbone,都是做一段時間發現不太合適就放棄了。當然這和可能個人開發習慣也有關係,不是說它們不好。

各種技術混用完全依賴構建工具(之前用grunt,後轉到了gulp,配置更方便)。不過我們用各種模板只是在開發階段,只是為了簡化html編寫,所以jade/haml這類用得最多,調試和發布時已經轉化為html了。你們之前的handlebars模板,應該是在運行時用吧,或者也可能是後台編譯,模板裡面包含邏輯,比如說變數、循環、條件判斷這些,我覺得可以通過directive,監控數據變化動態編譯模板。

我寫了個示例可以參考: angular_handlebars

&
&
&angular with handlebars&
&

只用過AngularJS,業餘玩過一下ReactJS。我就不發表意見了。

問:AngularJS值得學習和工作中使用嗎?

答:值得學習。工作中看實際需要使用,包括項目大小,前後台設計理念,以及最最重要的……你的team的人員的架構感、架構感、架構感、架構感、架構感還是架構感!!!

個人對AngularJS的情感曲線是,好奇--憎惡--喜歡

(如果你沒有數據結構、設計模式等概念,建議就此打住)

======================我是分割線=====================

好,下面一條一條說一下我對上述缺點的看法。

AngularJS引入概念過多。

要理解這個,首先要理解一個概念。網頁前端也是分「前後台」的。是的,你沒看錯,前端的前台,前端的後台。

在這個體系裡頭,前端的後台,由controller負責,重點留意$scope.XXXX,你從伺服器拿到的數據(例如一個http請求返回的json object),就存在這裡頭。前端的前台,由template、directive負責,他們決定了對一個對象的渲染方式。

在理解了這個之後,再去理解AngularJS的概念就相對容易了。簡單來說,controller負責數據結構,directive負責渲染方式。

service、provider、factory,其實都對應了一種常用的設計模式。具體可以參照 https://docs.angularjs.org/guide/providers

有設計模式、高內聚低耦合等意識的,理解AngularJS是比較容易。

ng-repeat

這個,和常用的後台渲染框架類似,區別就在於,一個跑在伺服器端,回傳整張html,一個跑在瀏覽器端,伺服器回傳json,全部解析,渲染在瀏覽器完成。

ng-click 和 onclick

ng-click是angular的一個內置directive,會經過編譯(也是在瀏覽器完成啦)然後對接到onclick事件重。

directive matching規則不容易對上

設計好的,怎麼都能對上,例如全部使用絕對路徑、大小寫敏感、規範命名規則,配套SyntaxCheck等。如果你說一個名字叫做A的directive,實際上對應了一個名字叫做B的template,這種UUID式的Mapping關係,想不亂都很難。

這種對應關係錯亂的,在後端渲染的模式也繞不開。像修改了DTO但忘了改JSP模板的事情沒發生得少?。區別在於,一個前端會得到500或者「知識的荒野」,一個會在瀏覽器的console報錯……

渲染周期詭異,不按劇本走啊!!

這確實是個問題。。。。但遇到得不多,真繞上了,一般來說……都是可以歸入「原來的設計不符合新的需求」這個梗上,重構可以解決。

操縱原生Dom元素會掉坑

directive是唯一可以直接操縱Dom的東西,包括編譯前、編譯後、渲染前、渲染後的各個環節,。細看文檔別無他法。大部分覺得開車看使用說明、上駕校理所應當,但寫代碼不懂的地方看看文檔,比登天還難……你不了解,能用得好?

雙向綁定元素過多時「據說會慢」

這裡可以寫個幾十萬字長篇小說……

這個結論出自不少評測,例如把原生Js啊,ReactJS啊,JQ啊,AngularJS啊,拿過來……一起生成100w個元素,哦,一個1秒,一個2秒,一個3秒。好,3秒那個很慢,性能不好……

拜託!!!當你一個頁面有100w數據的時候,會快到哪裡去!!趕緊讓產品狗分析需求重構頁面(我相信這裡用「重寫」比較合適……)!!!傳輸100w組數據,IO耗費20秒的情況下,渲染這2秒差別能差很遠?我覺得首先你得考慮用戶沒有在5秒內關閉頁面……

directive和controller之間的對應關係不明確,依賴注入不明確等

這顯然是屬於設計問題……不應該把爛設計用AngularJS實現而把這問題推給AngularJS。就跟不能某幾個人看武媚娘盯著人家的胸看,就推出全部人都會盯著人家的胸看,從而推出造成大面積家庭破裂的結論。

======================我是分割線=====================

下面說說AngularJS的好處

1, 服務端、瀏覽器分離。

用AngularJS來設計One Page App是極好。伺服器只負責數據校驗,回傳數據等,而瀏覽器那邊怎麼渲染,就和伺服器關係不大了。如果你有一個team,對前端後端都有極度擅長的人,那麼用AngularJS會很爽很爽。但這API介面得仔細設計。

2, 省IO(但這個我覺得不大重要)。

你想啊,以前是整張HTML生成完了回來,現在是分成一小部分一小部分,需要就載入,載入了就cache。傳輸的總大小是有了不小改進。

3, 純靜態化。

模板純靜態化,js純靜態化,css純靜態化。純靜態化意味著可以通過開啟瀏覽器Cache、廣泛使用CDN等技術來實現加速。

最終還是回到一個結論:設計很重要……數據結構很重要……設計模式很重要……真正能把事情做好的碼農很重要……

==== 更新 : 2016-05-14

很多人說寫directive很煩。

其實嘛 …… 可以在controller裡頭直接調用jq去動DOM。。我就偶爾這麼干!!

但是,我很清楚地知道我這樣做,並不會去觸碰angular託管的dom。。


抱歉只有AngularJS的經驗,使用AngularJS必須要Javascript基礎好,如果Javascript功力深,理解了它的框架原理,你會覺得它是萬能的,可與任何其他JS組件結合。如果Javascript功力低,你會覺得用它這也不會,那也不會,到處是缺點。


angular中,要理解directive的各種配置項的意思,以及相關的scope類型(繼承型、封閉型等),這些是重點(實際上僅從官網介紹這些內容的篇幅大小就可大概感知到)但其實這些並不太難,需要耐心學習理解就是。再學習下jquery插件等外部代碼在angular項目中整合的處理方式,以及各部分代碼該如何組織(angular教程里講各個概念時候基本都有提到其相應作用)等,這樣就能應付大多數的項目了。涉及到angular源碼的調試和理解,那是相對困難的地方。


AngularJS中不可以使用 Handlebars,要用handlerbars的話,請考慮ember.js


1:臟檢查性能問題

2:意義不大的模塊化

更好的推薦vue.js 或者 ng2 一套框架,多種平台 呀


Angularjs 有些過度設計的感覺。factory, provider, service controller, $scope。。。搞進來一大堆的名詞概念,其實是把問題搞複雜了。所謂的DI,我覺得對於js有些多餘。試過幾次,想在項目中用,卻只停留在了 Demo的級別。為了用好,還研究了幾天源代碼,要真用起來,坑還是很多的。和其他的框架對比了一下, backbone,ember,knockout,batmanjs等。 目前這些mv* 框架里最喜歡的是batmanjs,可能是 coffeescript的緣故,代碼看起來比較舒服,如果用過rails,會感覺比較親切。

如果真想用js做大工程的話,微軟的 typescript 應該是不錯解決方案。


之前沒有用過AngularJS,正好最近有個項目實踐了一下。

由於AngularJS中MV互相綁定,所以不可以使用 Handlebars;

AngularJS是一個非常複雜的框架,雖然入門比較容易,但是如果想要全面掌握學習曲線還是比較陡的;

在具體使用過程中很容易感受到其強大的地方,是未來發展的方向和趨勢。


## 說一說AngularJS的缺點

個人覺得最大的缺點就是 SEO

AngularJS 是一個 MVVM 的框架,也可以理解成一個瀏覽器端的 HTML 模板引擎。由於 HTML 的內容是通過數據綁定和 HTML 模板在瀏覽器端生成的,那麼搜索引擎在爬取這個頁面的時候,讀到的只是我們寫的 template,無法知道頁面真實的樣子,因為不會去執行一遍 JS 腳本。那搜索引擎就不能很好的收錄我們的網站,用戶就沒法找到我們的網站了。

## 那怎麼解決

請看這兩篇文章

http://angularjs.cn/A05v

http://stoneydream.com/2015/05/31/angularjs%E5%A6%82%E4%BD%95%E5%81%9Aseo/

基本思路就是區分對待:

對於正常用戶的訪問,伺服器響應AngularJS應用框架;對於搜索引擎的訪問,則響應專門針對SEO的HTML頁面(而不是AngularJS應用)。也就是說,SEO還是像普通網站那樣,在伺服器端處理的。

Github 上有個 Angular-SEO 的項目,採用的就是這種原理。

https://github.com/steeve/angular-seo


缺點多的去了,學習曲線陡峭,不支持IE6~8,實現機制極其複雜,比如臟檢查,性能低。由於跳崖式的更新,學習更加陡峭,網上的就教程都不知道看哪個。 2.0變化太大相當於新的一個mvvm。對國內的雙核瀏覽器和微信瀏覽器啥的支持不佳。 能都別這麼崇洋媚外么,搞得mvvm只有angular似得。


如果你不是做移動端的本地APP(我理解是安裝時JS文件等資源就是在本地的),國內的寬頻較慢的地區還是大有人在的,個人有用一段時間angular,非常強大,靈活度也很高,也很穩定。但是如果你追求輕巧和簡單上手,建議knockoutJS,是微軟的員工開發的,功能強大,上手非常快(相對angular),幾乎你看一次代碼看一個比較完整的demo就能學會各種API的使用。如果要使用route之類的可以配合使用sammy(官方的demo是用整個)或者pager。


這裡是一正、一反兩個觀點:

  • Angular.JS出了什麼問題?
  • 保衛AngularJS


winjs


我到覺得大項目基本上會用上自己定義的UI,angularjs其實很好做這些UI的底層。可以關注ionicframework.基於DOM模版的框架相對而言,更加符合未來的趨勢。


推薦閱讀:

React中的virtual dom是否可以理解為當前組件的view model?

TAG:前端開發 | JavaScript | MVC | MVVM | AngularJS |