??????? AngularJS能夠很好地與RequireJS( http://www.requirejs.org/ )配合使用,這使得我們可以同時(shí)擁有兩種組件的優(yōu)點(diǎn)。下面通過(guò)配置AngularJS官方的AngularSeed實(shí)例,來(lái)看一下AngularJS與RequireJS集成組織項(xiàng)目的方式。
??????? 項(xiàng)目結(jié)構(gòu):
??????? 首先,我們需要main.js文件,RequireJS將會(huì)加載這份文件,然后這份文件將會(huì)觸發(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)建的所有控制器、服務(wù)、指令及過(guò)濾器文件都必須寫(xiě)到這里,這塊內(nèi)容必須手動(dòng)維護(hù) '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' }); } ]); } );
??????? 然后定義一個(gè)app.js文件。這個(gè)文件定義了AngularJS應(yīng)用,并且告訴它去依賴我們所定義的所有控制器、服務(wù)、過(guò)濾器及指令。
??????? 你可以把RequireJS依賴列表看作JavaScript版的阻塞型import語(yǔ)句。也就是說(shuō),除非依賴列表中的內(nèi)容都已經(jīng)加載完或準(zhǔn)備好,否則語(yǔ)句塊中的函數(shù)不會(huì)開(kāi)始執(zhí)行。
??????? 同時(shí)要注意,我們不會(huì)單獨(dú)讓RequireJS去加載指令、服務(wù)或過(guò)濾器,因?yàn)檫@不是當(dāng)前這個(gè)項(xiàng)目的組織方式。對(duì)于每個(gè)控制器、服務(wù)、過(guò)濾器及指令,都有一個(gè)模塊與之對(duì)應(yīng),因此,只要把這些模塊定義成我們所依賴的東西就夠了。
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文件,它將會(huì)等待DOM結(jié)構(gòu)準(zhǔn)備好(使用RequireJS的插件domReady),然后告訴AngularJS一切都已就緒,可以開(kāi)始運(yùn)行了。
bootstrap.js
//當(dāng)DOM結(jié)構(gòu)加載完成后,bootstrap.js文件將會(huì)命令A(yù)ngularJS啟動(dòng)起來(lái)并繼續(xù)執(zhí)行 define(['angular', 'domReady', 'app'], function(angular, domReady) { require(['domReady!'], function (document) { angular.bootstrap(document, ['app']); }); });
??????? 把啟動(dòng)過(guò)程和應(yīng)用代碼分離開(kāi)還有另一個(gè)好處,那就是,為了測(cè)試,我們可能會(huì)潛在地把mainApp替換成虛擬的代碼或者mockApp。例如,如果所依賴的服務(wù)器是不可靠的,你可能會(huì)創(chuàng)建一個(gè)fackApp,用來(lái)代替所有$http請(qǐng)求,它會(huì)返回一些虛擬的數(shù)據(jù)來(lái)保證開(kāi)發(fā)過(guò)程順利進(jìn)行。這樣一來(lái),你可能只是把fakeBootstrap和fackApp放到了應(yīng)用中。
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>
??????? 下面來(lái)看看js/controllers/controllers.js文件里面的內(nèi)容,它看起來(lái)幾乎和js/directives/directives.js、js/filters/filters.js及js/services/services一模一樣。
define(['angular'], function (angular) { 'use strict'; return angular.module('controllers', []); });
??????? 我們組織RequireJS依賴關(guān)系的方式會(huì)保證在Angular所依賴的內(nèi)容加載并準(zhǔn)備好之后,所有的東西才會(huì)運(yùn)行。
??????? js/controllers/、js/directives/、js/filters/及js/services/里面都會(huì)定義一個(gè)AngularJS模塊,并且對(duì)于每一個(gè)單獨(dú)的控制器、指令、過(guò)濾器及服務(wù),在聲明的時(shí)候都會(huì)添加對(duì)應(yīng)的模塊依賴。
js/controllers/index.js
define([ './my-ctrl-1', './my-ctrl-2' ], function () {});
js/directives/index.js
define(['./app-version'], function () {});
再進(jìn)一步看一下控制器和指令的定義:
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); }; }]); });
??????? 指令本身是非常瑣碎的,但是我們還是來(lái)仔細(xì)看一下正在發(fā)生什么事情。RequireJS將會(huì)在文件兩端添加一些東西,這些東西會(huì)說(shuō)我的app-version.js文件會(huì)依賴模塊聲明文件directives/directives.js。然后這份文件就會(huì)使用插入了指令的模塊去添加自已的指令聲明。你可以把單條或者多條指令放在同一份文件里面,這完全由你自已決定。
??????? 其中有一個(gè)主要的注意點(diǎn):如果你有一個(gè)控制器,且這個(gè)控制器會(huì)從一個(gè)后臺(tái)服務(wù)中拉取數(shù)據(jù)(例如RootConroller依賴于UserService,它被注入了UserService),這種情況下,你就必須確保在RequireJS中也定義了服務(wù)文件的依賴,示例如下:
define(['controllers/controllers', 'services/services'], function(controllers) { controllers.controller('RootController', ['$scope', 'UserService', function($scope, UserService) { //做需要做的事情 }; }]); });
??????? 以上就是整個(gè)源碼文件夾基本的配置方式。
?
參考書(shū)籍:《用AngularJS開(kāi)發(fā)下一代Web應(yīng)用》
參考源碼: https://github.com/StarterSquad/startersquad.com/tree/master/examples/angularjs-requirejs-1
?
附件工程源碼:
1.原來(lái)的AngularJSSeed工程源碼AngularJSSeed.rar
2.與RequireJS集成后的工程源碼AngularRequireSeed.rar
3.github上的工程源碼AngularRequireJSSeed.rar
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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