??????? AngularJS能夠很好地與RequireJS( http://www.requirejs.org/ )配合使用,這使得我們可以同時擁有兩種組件的優(yōu)點。下面通過配置AngularJS官方的AngularSeed實例,來看一下AngularJS與RequireJS集成組織項目的方式。
??????? 項目結構:
??????? 首先,我們需要main.js文件,RequireJS將會加載這份文件,然后這份文件將會觸發(fā)加工其他所有依賴的東西。
main.js
/** * 定義RequireJS配置 */ require.config({ paths: { 'angular': '../lib/angular/angular', 'angular-route': '../lib/angular-route/angular-route', 'domReady': '../lib/requirejs-domready/domReady' }, shim: { 'angular': { exports: 'angular' }, 'angular-route': { deps: ['angular'] } }, deps: [ // kick start application... see bootstrap.js './bootstrap' ] }); require( [ 'app', //注意:這不是Twitter Bootstrap,而是AngularJS bootstrap 'bootstrap', //所創(chuàng)建的所有控制器、服務、指令及過濾器文件都必須寫到這里,這塊內(nèi)容必須手動維護 'controllers/controllers', 'services/services', 'directives/directives', 'filters/filters' ], function(app) { 'use strict'; return app.config( [ '$routeProvider', function($routeProvider) { $routeProvider.when('/view1', { templateUrl : 'partials/partial1.html', controller : 'MyCtrl1' }); $routeProvider.when('/view2', { templateUrl : 'partials/partial2.html', controller : 'MyCtrl2' }); $routeProvider.otherwise( { redirectTo : '/view1' }); } ]); } );
??????? 然后定義一個app.js文件。這個文件定義了AngularJS應用,并且告訴它去依賴我們所定義的所有控制器、服務、過濾器及指令。
??????? 你可以把RequireJS依賴列表看作JavaScript版的阻塞型import語句。也就是說,除非依賴列表中的內(nèi)容都已經(jīng)加載完或準備好,否則語句塊中的函數(shù)不會開始執(zhí)行。
??????? 同時要注意,我們不會單獨讓RequireJS去加載指令、服務或過濾器,因為這不是當前這個項目的組織方式。對于每個控制器、服務、過濾器及指令,都有一個模塊與之對應,因此,只要把這些模塊定義成我們所依賴的東西就夠了。
app.js
define([ 'angular', 'angular-route', './controllers/index', './directives/index', './filters/index', './services/index' ], function (angular) { 'use strict'; return angular.module('app', [ 'controllers', 'directives', 'filters', 'services', 'ngRoute' ]); });
?????? 我們還有一份bootstrap.js文件,它將會等待DOM結構準備好(使用RequireJS的插件domReady),然后告訴AngularJS一切都已就緒,可以開始運行了。
bootstrap.js
//當DOM結構加載完成后,bootstrap.js文件將會命令AngularJS啟動起來并繼續(xù)執(zhí)行 define(['angular', 'domReady', 'app'], function(angular, domReady) { require(['domReady!'], function (document) { angular.bootstrap(document, ['app']); }); });
??????? 把啟動過程和應用代碼分離開還有另一個好處,那就是,為了測試,我們可能會潛在地把mainApp替換成虛擬的代碼或者mockApp。例如,如果所依賴的服務器是不可靠的,你可能會創(chuàng)建一個fackApp,用來代替所有$http請求,它會返回一些虛擬的數(shù)據(jù)來保證開發(fā)過程順利進行。這樣一來,你可能只是把fakeBootstrap和fackApp放到了應用中。
index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>AngularJS與RequireJS集成App</title> <link rel="stylesheet" href="css/app.css"> </head> <body> <ul class="menu"> <li><a href="#/view1">view1</a></li> <li><a href="#/view2">view2</a></li> </ul> <div data-ng-view></div> <div>Angular Require seed app: v<span app-version></span></div> <script src="lib/requirejs/require.js" data-main="js/main.js"></script> </body> </html>
??????? 下面來看看js/controllers/controllers.js文件里面的內(nèi)容,它看起來幾乎和js/directives/directives.js、js/filters/filters.js及js/services/services一模一樣。
define(['angular'], function (angular) { 'use strict'; return angular.module('controllers', []); });
??????? 我們組織RequireJS依賴關系的方式會保證在Angular所依賴的內(nèi)容加載并準備好之后,所有的東西才會運行。
??????? js/controllers/、js/directives/、js/filters/及js/services/里面都會定義一個AngularJS模塊,并且對于每一個單獨的控制器、指令、過濾器及服務,在聲明的時候都會添加對應的模塊依賴。
js/controllers/index.js
define([ './my-ctrl-1', './my-ctrl-2' ], function () {});
js/directives/index.js
define(['./app-version'], function () {});
再進一步看一下控制器和指令的定義:
my-ctrl-1.js
define(['controllers/controllers'], function (controllers) { 'use strict'; controllers.controller('MyCtrl1', [function ($scope) {}]); });
my-ctrl-2.js
define(['controllers/controllers'], function (controllers) { 'use strict'; controllers.controller('MyCtrl2', [function ($scope) {}]); });
app-version.js
define(['directives/directives'], function (directives) { 'use strict'; directives.directive('appVersion', ['version', function (version) { return function (scope, elm) { elm.text(version); }; }]); });
??????? 指令本身是非常瑣碎的,但是我們還是來仔細看一下正在發(fā)生什么事情。RequireJS將會在文件兩端添加一些東西,這些東西會說我的app-version.js文件會依賴模塊聲明文件directives/directives.js。然后這份文件就會使用插入了指令的模塊去添加自已的指令聲明。你可以把單條或者多條指令放在同一份文件里面,這完全由你自已決定。
??????? 其中有一個主要的注意點:如果你有一個控制器,且這個控制器會從一個后臺服務中拉取數(shù)據(jù)(例如RootConroller依賴于UserService,它被注入了UserService),這種情況下,你就必須確保在RequireJS中也定義了服務文件的依賴,示例如下:
define(['controllers/controllers', 'services/services'], function(controllers) { controllers.controller('RootController', ['$scope', 'UserService', function($scope, UserService) { //做需要做的事情 }; }]); });
??????? 以上就是整個源碼文件夾基本的配置方式。
?
參考書籍:《用AngularJS開發(fā)下一代Web應用》
參考源碼: https://github.com/StarterSquad/startersquad.com/tree/master/examples/angularjs-requirejs-1
?
附件工程源碼:
1.原來的AngularJSSeed工程源碼AngularJSSeed.rar
2.與RequireJS集成后的工程源碼AngularRequireSeed.rar
3.github上的工程源碼AngularRequireJSSeed.rar
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
