angularjs的設(shè)計(jì)理念是鼓勵(lì)多模塊的,每個(gè)模塊可以依賴于其它模塊,這樣可以用模塊的概念匹配業(yè)務(wù)功能。所以在設(shè)計(jì)angularjs的程序時(shí),可以根據(jù)一定的業(yè)務(wù)規(guī)則進(jìn)行模塊劃分。
一般來講,一個(gè)angularjs的程序都會(huì)有一個(gè)app模塊,也就是程序的入口點(diǎn)。當(dāng)然如果功能較少,一個(gè)app模塊就足夠了,剩下的service和controller等其他組件都可以掛到這個(gè)app上。但是程序一擴(kuò)張,就需要更好的模塊設(shè)計(jì)來處理模塊之間的依賴關(guān)系,以及模塊與外部組件之間的依賴關(guān)系(結(jié)合requirejs)。
在這個(gè)項(xiàng)目中,模塊是根據(jù)菜單關(guān)系進(jìn)行切割的,比如系統(tǒng)管理是個(gè)一級菜單,然后下面會(huì)有多個(gè)二級菜單,例如有一個(gè)LDAP管理子菜單。下面是這個(gè)功能的目錄結(jié)構(gòu):
可以看到,在一級菜單下面會(huì)有一個(gè)app-system.module.js的文件,這個(gè)文件里會(huì)結(jié)合ui-router-extras庫用來動(dòng)態(tài)加載一級菜單下的路由配置。然后ldap二級菜單下會(huì)有一個(gè)system-ldap.module.js文件,這個(gè)文件里沒有什么業(yè)務(wù)功能邏輯,但ldap下面的那些controller都會(huì)掛到這個(gè)模塊下。
看一下具體的代碼:
app-system.module.js
define(["require", "angular", 'utils/routerHelper', 'modules/system/system.routes', "angular-select"], function (require, ng, routerHelper, routerCfg) { var module = angular.module('app.system', ['ngAnimate', "ui.router", "ui.bootstrap", "ui.select",'ngSanitize']); routerHelper.call(module, routerCfg); return module; });具體怎么動(dòng)態(tài)加載路由,下篇文章在講。這個(gè)文件主要的作用:1)通過requirejs加載一級菜單下需要的一些公用外部組件,2)把一級菜單下依賴的其它angularjs模塊加載進(jìn)來,3)可以在這個(gè)文件里繼續(xù)掛載一級菜單下需要的公用directive或者filter等其他angularjs組件譬如可以繼續(xù)這樣寫:
...module.constant("INDEX_COLORS",[].concat(Highcharts.getOptions().colors)); module.factory('randomColorUtils', ['INDEX_COLORS',function(INDEX_COLORS){ return { generateColors : function(objs){ angular.forEach(objs,function(val,key){ val.color = INDEX_COLORS[key % INDEX_COLORS.length]; }); } }}]);module.directive('optionsExtAttr', ['$parse','$timeout',function ($parse,$timeout) {...}]);...然后這個(gè)模塊下的所有子菜單功能就可以使用這些組件了。system-ldap.module.js
define(["require","angular"], function(require,ng) { var module = angular.module('app.system.ldap',[]); return module;});這個(gè)例子看,此模塊沒有實(shí)質(zhì)性的意義,但其實(shí)可以有和上一層模塊同樣的作用,就是處理二級菜單下獨(dú)有的依賴以及angularjs組件。最后看一下ldap里面的組件怎么掛到app.system.ldap上:
define(['require','angular','ngload!modules/system/ldap/system-ldap.module','modules/system/ldap/ldap.service'], function(require,ng,module){ module.controller('LDAPCtrl',['$scope','ldapSrv','uiGridUtils','modalUtils', function($scope,ldapSrv,uiGridUtils,modalUtils){ }])})這里需要借助angularAMD的ngload組件把module動(dòng)態(tài)load進(jìn)來。至于app.system模塊怎么load進(jìn)來,在介紹程序啟動(dòng)入口的文章中在詳細(xì)寫。
如果有三級,甚至四級菜單,需不需要在往下創(chuàng)建單獨(dú)的module文件,個(gè)人認(rèn)為可能沒有必要了,因?yàn)閙odule文件太多了,也沒有啥實(shí)質(zhì)作用。當(dāng)然了如果業(yè)務(wù)邏輯特別復(fù)雜, 也可以繼續(xù)建module文件,沒什么硬性的要求。
上面這種模塊劃分只是給了一種參考實(shí)現(xiàn),未必適用各種項(xiàng)目,其實(shí)劃分模塊的目的主要是讓功能模塊和業(yè)務(wù)模塊相對應(yīng),利于后期維護(hù)擴(kuò)展。
新聞熱點(diǎn)
疑難解答
圖片精選