【墨磊的回答(128票)】:
謝提醒,之前還沒(méi)注意到這個(gè)。
最近做的某個(gè)項目的 UI 部分 Mobile Campus(Google Drive 可能需要跨墻)
代碼:https://github.com/morlay/angular-mobile-ui
然后,說(shuō)說(shuō)我的一些做法??赡懿粔蛲晟?,畢竟還在折騰中。
## DOM 的整體 or 零散
首先是這篇神貼:
javascript - How do I "think in AngularJS" if I have a jQuery background?
AngularJS 與 jQuery 等傳統操作 DOM 的思想有所不同,
對于 jQuery 等,一般是先有完整 DOM 然后在這些 DOM 的基礎上進(jìn)行二次調教。
而 AngularJS 等框架則是 根據 數據模型 以及其對應的 DOM 模版,然后通過(guò)模版像搭積木那樣組合頁(yè)面。
顯然的,前者在 SEO 上有天然優(yōu)勢;而后者,搜索引擎還只能拿到某個(gè)模版,而無(wú)內容。
暫時(shí)沒(méi)想到有什么特別好的解決方案,或許,對于內容頁(yè),可以繼續使用傳統方式,而只在需要更多交互的地方應用 AngularJS,特別是在移動(dòng)端應用上。
同理適用于各種 前端的 MVC 框架,后端只要為前端提供數據接口,而不再需要為其拼接 HTML.
## 模塊化
AngularJS 也是遵循 AMD 的。(AMD 是啥,參考:使用 AMD、CommonJS 及 ES Harmony 編寫(xiě)模塊化的 JavaScript)
雖然它也可以按照傳統代碼方式來(lái)寫(xiě)(其首頁(yè)介紹的用法 AngularJS — Superheroic JavaScript MVW Framework),但是,既然都提供了這么一種模塊的方法,為何不用上呢 (參考下他已有的較成熟衍生庫 https://github.com/angular-ui/bootstrap)。
angular.module('app', [ 'moduleA', 'moduleB',]).controller('MainCtrl', [ '$scope', function ($scope) {}]);
而且,這種寫(xiě)法還可以方便做代碼的合并與壓縮,在后面 Grunt 自動(dòng)化 一節中,就會(huì )提到使用 Nodejs/Grunt 來(lái)自動(dòng)的做這些事情。
## 可復用模版 or 業(yè)務(wù)邏輯模版
今年 Google 開(kāi)發(fā)者大會(huì )中 提到的 Polymer(Welcome - Polymer)
這貨讓人感覺(jué)像是 Angular Directives 的進(jìn)化。
而 Directives 做的事,就是把一堆 DOM 封裝為一條或者一組 自定義的 HTML標簽,作為可復用的模版,以供組裝業(yè)務(wù)調用。 Demos 可參看:Angular directives for Twitter's Bootstrap
當然,為了方便修改,很多時(shí)候在做 directive 的時(shí)候需要將 template 用 templateUrl 代替,
不用擔心文件的碎片化,不利于前端加載 Grunt 自動(dòng)化 一節 會(huì )提到如何合并這些碎片化的 模版。
Directives 是作為可復用的模版,
而業(yè)務(wù)邏輯則是一般是一個(gè)業(yè)務(wù)對應一個(gè) html 及其的 controller.
## 作用域間的通信
上節提到了一個(gè) html 及其的 controller,一個(gè)完整應用自然會(huì )包含很多的業(yè)務(wù)子塊。
自然會(huì )有很多很多 cotrollers.
AngularJS 提供了 方法, $scope 或者 $rootScope 的 $broadcast $emit / $on
$scope.$emit('eventA',msg); $scope.$broadcast('eventA',msg); $rootScope.$on('eventA',function(event,msg){ console.log(msg);});
至于他們之間的差別,可參考這個(gè) Demo, Chrome F12 ,你可以看到結果。
https://googledrive.com/host/0Bwdui5aYcEA9SzN2WDJ4cXZRTTA/index.html
## 數據池
除了作用域間的傳值外,還有個(gè)方法是統一的管理一個(gè)數據池,
對于沒(méi)有業(yè)務(wù)交叉的 controller,若是有公有數據的需要,都從這個(gè)數據池中取,
而這個(gè)數據池更可以直接作為和后端數據的統一交互口,及本地緩存管理的地方。
## Grunt 自動(dòng)化
Grunt(Grunt: The JavaScript Task Runner)出現以后,我是發(fā)現 Git 上面基本上前端相關(guān)的項目上都多了個(gè) Gruntfile.js,可見(jiàn)他確實(shí)好用。
不太喜歡大多數項目中把所有任務(wù)都丟在一個(gè)文件里的方式。
所以,利用 node.js 的特性,將任務(wù)集也分解開(kāi)來(lái)。
在 https://github.com/morlay/angular-mobile-ui 這里可以看到對應的代碼。

這里只說(shuō)說(shuō),如何按照 angular module 的依存關(guān)系自動(dòng)合并對應文件。
https://github.com/morlay/angular-mobile-ui/blob/develop/grunt/subTasks/angular-concat-modules.js
首先是模塊的命名,使得它能夠和它的路徑一致性。


看這兩張圖就明白了??催@兩張圖就明白了。
第二,除了特殊的,全局公用的模塊外,
其他模塊在各自業(yè)務(wù)組件中建立引用關(guān)系。
避免載入多余的模塊。

比如這里,我只需要把 Grunt 配置中,比如這里,我只需要把 Grunt 配置中,
把 app.main 作為了入口文件,
并配置它的全局引用,ngMobile 和 tpls(可復用模版轉換而成的 js)
通過(guò) `grunt angular-concat-modules` 和 `grunt script-uglify`

合并壓縮自動(dòng)完成。合并壓縮自動(dòng)完成。
當然,這里更是直接做了任務(wù),`grunt release` 一條指令搞定一切。
而,對于 angular 模版轉換為 js 有現成的 grunt-angular-templates 可用,
這里不細說(shuō)了,詳看代碼。
## 測試工具
最后的,關(guān)于測試工具,官方有提供 Karma - Spectacular Test Runner for Javascript
但沒(méi)用過(guò),也不知道怎么用,希望有同行給予補充與介紹。
其他的,在 API 文檔里寫(xiě)得挺詳細的。
P.S.
至于知乎,并非完全 Angular 的方式,
希望能夠進(jìn)一步,至少在不需要 SEO 的部分。
繼續折騰去了,還有很多東西要弄。
【willerce的回答(5票)】:
怎么解決搜索引擎的問(wèn)題?
在接收到請求后,判斷如果是來(lái)自搜索引擎的抓蟲(chóng),就展示該 URL 應該顯示的內容。
而如果是用戶(hù)請求,那么這邊應該輸出指定的 Web MVC 框架的入口,框架再通過(guò) URL 判斷需要加載的內容通過(guò) API 向后端請求,得到數據后,渲染。
簡(jiǎn)單講:
抓蟲(chóng):輸出內容完整的 HTML
用戶(hù):輸出沒(méi)有內容的 HTML,然后 JS 自己再通過(guò) API 請求內容渲染。
貼一下 jsgen 處理抓蟲(chóng)的代碼:
var robotReg = new RegExp('Baiduspider|Googlebot|BingBot|Slurp!', 'i');if (robotReg.test(req.useragent)) { //是搜索引擎爬蟲(chóng),輸出靜態(tài)頁(yè)面}
【知乎用戶(hù)的回答(3票)】:
1. 面向數據編程
使用angularjs的思路簡(jiǎn)單:1)界面元素綁定數據,2)操作處理數據
我用這個(gè)思路編寫(xiě)了一個(gè)冒泡算法的可視化,實(shí)現十分簡(jiǎn)單,想清楚如何綁定數據后,接下來(lái)的工作就只是操作處理數據了。
相比如果使用jQuery,jQuery的思想是面向界面元素編程,簡(jiǎn)單的說(shuō)如何定位和操作界面(網(wǎng)頁(yè))元素,大量精力放在了界面元素的操作上,而應該是重點(diǎn)的數據處理卻在這個(gè)思路體系中占了很小的位置。
2. 可測試模塊化編程
這個(gè)思路有兩點(diǎn),1)模塊化 2)可測試
angularjs雖然可以很傻瓜式的編程,但是更加推薦的還是模塊化編程,而且是可測試模塊化編程。它的教程也一直把如何測試模塊的方式也寫(xiě)了進(jìn)去。
angularjs剛出來(lái)的時(shí)候,最詬病的地方,就是測試困難,也是backbone和其他框架使用者對它的質(zhì)疑。后來(lái)angularjs team花了很大的精力去解釋angularjs如何測試,如何依賴(lài)注入,如何提高angularjs的可靠性。后來(lái)把官方網(wǎng)站把所有的例子上,都包括了相應的測試代碼。很好的回應了難以測試的質(zhì)疑。
angularjs,本身有很多模塊,而且推薦以模塊的形式編寫(xiě)angularjs插件。很大一塊是教人如何寫(xiě)service,route和Declarative , 這些之間又是相互獨立的模塊,有可以把這些模塊有機的組合在一起。
3. 前端模板引擎
angularjs本身是很好的前端模板引擎,未來(lái)發(fā)展就是后端的mvc產(chǎn)生json視圖(view)作為前端的模型(model),而整個(gè)前端的mvc是后端的視圖(view),中間通信就靠json。這樣前后端高度解耦,可以完全達到模塊化設計的要求。
這樣前端只要知道后端產(chǎn)生數據的結構,給了一些數據樣本,就可以直接開(kāi)發(fā)了,而無(wú)需等待后端代碼完成。
這個(gè)答案是我來(lái)說(shuō)明網(wǎng)站開(kāi)發(fā)的未來(lái)趨勢:
請簡(jiǎn)單說(shuō)明 angularJS 有什么用?
-----暫時(shí)先寫(xiě)到這里,有了更多感悟再寫(xiě)----
【Ninstein的回答(2票)】:
關(guān)于SEO友好的,可以看看這個(gè) Google On pushState Versus Hashbang (#!)
【W(wǎng)uvist的回答(0票)】:
怎么解決搜索引擎的問(wèn)題?
Making AJAX Applications Crawlable
【李志偉的回答(0票)】:
用了幾個(gè)月,模塊化設計的確非常不錯,還有一些AngularJs本身自帶的插件和bootStrap的結合也是不錯和nodejs用起來(lái)還是挺配的,后端業(yè)務(wù)邏輯簡(jiǎn)化不少,但是缺點(diǎn)也非常明顯,瀏覽器兼容性,以及Angular本身功能缺失,以及對一些js插件支持的不友好,使用起來(lái)麻煩,加上入門(mén)稍微復雜點(diǎn)了,不是瞬間上手的類(lèi)型
【tommyhu的回答(0票)】:
mark
講的很不錯,node.js+radis+express+angularjs+bootstrap使用很經(jīng)典
【永丁的回答(0票)】:
國內的確用的不多,但我們是一個(gè),規模算大,用的人100左右,代碼100w行以上,以后還會(huì )增加。十多個(gè)系統,金融類(lèi)核心系統。
經(jīng)驗個(gè)人積累一點(diǎn),可能和做互聯(lián)網(wǎng)應用尤其是spa不太一樣。
1. 業(yè)務(wù)類(lèi)系統,趕快用吧,代碼量少一半一般,越復雜優(yōu)勢越明顯
2. 性能很多坑,網(wǎng)上的方案不夠用的,ie8下很多不能直接the angular way,延遲加載是王道,多次bootstrap也常有,直接改源碼常有
3. ui控件太少,完整套的要團隊自己開(kāi)發(fā)維護,個(gè)性化需求更需要從最底層定制
4. 官方的檢驗機制要吃透,復雜檢驗需求變化很多,要設計足夠靈活,用watch $error方式又有性能坑
5. 指令是個(gè)好東西,重客戶(hù)端組件化的方向,要理解透,用好
6. 模型設計上,服務(wù)端的貧血,充血之分這里可以借鑒。另外模型分類(lèi)命名空間很重要
如果你的頁(yè)面不復雜,就沒(méi)那么多講究了
最后,seo的,建議html兩套,angular有類(lèi)似工具
【陳暉鎧的回答(0票)】:
我沒(méi)有了解過(guò) Angular Seo 方面的知識,不過(guò)這一個(gè)多月看源碼下來(lái)我發(fā)現 Angular 其實(shí)很簡(jiǎn)單,當然我只看了關(guān)鍵的概念(指令、模板、臟檢測等),唯一能分享的是兩篇對源碼的解析,希望對你有幫助.
AngularJs ng-repeat 必須注意的性能問(wèn)題
原文地址:知乎
聯(lián)系客服