AngularJS是如今最受歡迎的JS框架之一,簡化開發過程是它的目標之一,這使得它非常適合於元型較小的apps的開發,但也擴展到具有全部特征的客戶端應用的開發。易於開發、較多的特征及較好的效果導致了較多的應用,伴隨而來的是一些陷阱。本文列舉了AngularJS的一些共同的易於也問題的地方,尤其是在開發一個app的時候。
AngularJS是一個缺乏較好的term的MVC框架,其models不像backbone.js中那樣做為一個框架來定義,但其結構模式仍匹配的較好。當在一個MVC框架中作業時,基於文件類型將文件組合在一起是其共同的要求:
templates/
_login.html
_feed.html
app/
app.js
controllers/
LoginController.js
FeedController.js
directives/
FeedEntryDirective.js
services/
LoginService.js
FeedService.js
filters/
CapatalizeFilter.js
這樣的布局, 尤其是對那些有 Rails 背景的人來說, 看起來挺合理. 可是當 app 變得越來越龐大的時候, 這樣的布局結構會導致每次都會打開一堆文件夾. 無論你是用 Sublime, Visual Studio, 還是 Vim with Nerd Tree, 每次都要花上很多時間滑動滾動條浏覽這個目錄樹來查找文件.
如果我們根據每個文件隸屬的功能模塊來對文件分組, 而不是根據它隸屬的層:
app/
app.js
Feed/
_feed.html
FeedController.js
FeedEntryDirective.js
FeedService.js
Login/
_login.html
LoginController.js
LoginService.js
Shared/
CapatalizeFilter.js
那麼查找某個功能模塊的文件就要容易得多, 自然可以提高開發的速度. 也許把 html 文件跟 js 文件放在混合放在一起做法不是每個人都能認同. 但是起碼它省下寶貴的時間.
一開始就將主模塊中所有子模塊展示出來是通常的做法。但是開始做一個小應用還好,但是做大了就不好管理了。
var app = angular.module('app',[]);app.service('MyService', function(){
//service code});app.controller('MyCtrl', function($scope, MyService){
//controller code});
一個比較好的辦法是將相似類型的子模塊分組:
var services = angular.module('services',[]);services.service('MyService', function(){
//service code});var controllers = angular.module('controllers',['services']);controllers.controller('MyCtrl', function($scope, MyService){
//controller code});var app = angular.module('app',['controllers', 'services']);
這個方法與上面那個方法效果差不多,但是也不很大。運用要分組的思想將使工作更容易。
var sharedServicesModule = angular.module('sharedServices',[]);
sharedServices.service('NetworkService', function($http){});
var loginModule = angular.module('login',['sharedServices']);
loginModule.service('loginService', function(NetworkService){});
loginModule.controller('loginCtrl', function($scope, loginService){});
var app = angular.module('app', ['sharedServices', 'login']);
當創建一個大的應用時,所有模塊可能不會放在一頁裡,但是將模塊根據類型進行分組將使模塊的重用能力更強。
3 依賴注入
依賴注入是AngularJS最棒的模式之一。它使測試變得更加方便,也讓它所依賴的對象變的更加清楚明白。AngularJS 對於注入是非常靈活的。一個最簡單的方式只需要為模塊將依賴的名字傳入函數中:
var app = angular.module('app',[]);app.controller('MainCtrl', function($scope, $timeout){
$timeout(function(){
console.log($scope);
}, 1000);});
這裡,很清楚的是MainCtrl依賴於$scope和$timeout。
直到你准備投入生產並壓縮你的代碼。使用UglifyJS,上面的例子會變成:
var app=angular.module("app",[]);
app.controller("MainCtrl",function(e,t){t(function(){console.log(e)},1e3)})
現在AngularJS怎麼知道MainCtrl依賴什麼?AngularJS提供了一個非常簡單的解決方案:把依賴作為一個字符串數組傳遞,而數組的最後一個元素是一個把所有依賴作為參數的函數。
app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout){
$timeout(function(){
console.log($scope);
}, 1000);}]);
接下來在壓縮的代碼中AngularJS也可以知道如何找到依賴:
app.controller("MainCtrl",["$scope","$timeout",function(e,t){t(function(){console.log(e)},1e3)}])
希望你喜歡,並分享我的工作~帶你走近AngularJS系列:
如何在 AngularJS 中對控制器進行單元測試 http://www.linuxidc.com/Linux/2013-12/94166.htm
在 AngularJS 應用中通過 JSON 文件來設置狀態 http://www.linuxidc.com/Linux/2014-07/104083.htm
AngularJS 之 Factory vs Service vs Provider http://www.linuxidc.com/Linux/2014-05/101475.htm
AngularJS —— 使用 ngResource、RESTful APIs 和 Spring MVC 框架提交數據 http://www.linuxidc.com/Linux/2014-07/104402.htm
通常在寫AngularJS應用時會有一個對象作為依賴綁定到全局作用域中。這意味著它在任何AngularJS的代碼中都可用,但這打破了依賴注入模型同時帶來一些問題,特別是在測試中。
AngularJS把這些全局變量封裝到模塊中,這樣它們可以像標准AngularJS模塊一樣被注入。
Underscore.js是很棒的庫,它把Javascript代碼簡化成了函數模式,並且它可以被轉化成一個模塊:
var underscore = angular.module('underscore', []);underscore.factory('_', function() {
return window._; //Underscore must already be loaded on the page});var app = angular.module('app', ['underscore']);app.controller('MainCtrl', ['$scope', '_', function($scope, _) {
init = function() {
_.keys($scope);
}
init();}]);
它允許應用繼續用AngularJS依賴注入的風格,也讓underscore在測試的時候被交換出來。
這或許看上去不重要,像是一個無關緊要的工作,但如果你的代碼正在使用use strict(應該使用),那麼這就變得有必要了。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-10/107783p2.htm