回顧javascript
上一篇文章主要講解了建立兼容任意瀏覽器(主要是ie的一些奇葩問題)的angularjs web應用,可是項目開發中其實更重要的仍是在功能的模塊化、代碼自動壓縮上面,這樣項目在後期維護或者功能的重複利用上纔會更方便,那麼今天主要圍繞如下幾個主題來說講如何在不是用其餘js模塊化庫的狀況下,開發便於管理的angualrjs模塊化代碼:html
本文中的代碼均已nodejs來實現。java
nodejs中,使用UglifyJS2來實現代碼壓縮node
使用service來建立模塊git
之前建立angualrjs應用都是直接基於對scope的直接綁定來完成的,例如:登陸功能,代碼以下:angularjs
//html <div ng-controller="loginController"> <div> 用戶名: <input type="text" ng-model="name" /> </div> <div> 密 碼: <input type="password" ng-model="pwd" /> </div> <a href="javascript:void(0)" ng-click="login()"> 登陸 </a> </div> //js var myApp = angular.module('myApp', []); myApp.controller('loginController', function ($scope) { $scope.name = ''; $scope.pwd = ''; $scope.login = function () { //代碼略 }; });
當有不少的功能的時候,有些人可能會建立不少的controller來完成,也有些人會像我同樣,使用一些js模塊化庫(seajs\requirejs)來實現,可是整合js模塊化庫會帶來一些問題,並且效果也不盡人意,代碼也會變得很複雜。github
鑑於以上的一些問題,我不得不尋找一些其餘的方案來替代,因而後來就想到了使用service來替代模塊化(多是資質比較差的緣由吧),這樣即可以充分利用angularjs的特性來完成,首先建立一個user的service,其實就是將當前scope內的代碼遷移到user.js內,代碼以下:web
myApp.service('user', function () { function User() { this.name = ''; this.pwd = ''; } User.prototype.login = function () { //代碼略 }; return new User(); });
而後只要稍微修改一下上面的代碼即可以實現這個功能了,改完代碼以下:瀏覽器
//html <div ng-controller="loginController"> <div> 用戶名: <input type="text" ng-model="user.name" /> </div> <div> 密 碼: <input type="password" ng-model="user.pwd" /> </div> <a href="javascript:void(0)" ng-click="user.login()"> 登陸 </a> </div> //js myApp.controller('loginController', function ($scope, user) { $scope.user = user; });
使用這種方法,功能開發就簡單多了,只要將功能的代碼變成一個個的js,而後頁面上引用後在controller初始化的時候,一個個綁定到scope上就能夠了。緩存
模塊間引用
項目開發當中,免不了模塊之間的交互,因爲以上咱們只用了service來建立模塊,而angularjs的service跟許多js模塊化庫是同樣的,不容許模塊之間的循環引用,這樣若是咱們有一個user和userAddress,當user須要引用userAddress的時候就會遇到一些問題。
遇到此類問題的時候,其實能夠引入一個相似緩存的模塊來解決,首先將全部的功能模塊都加入到緩存模塊中(controller內),而後當user模塊須要引用到userAddress模塊的時候,只要引用緩存模塊並從其開放的接口中獲取userAddress模塊便可。
其實緩存模塊就只要有2個方法(get\set),大體代碼以下:
myApp.controller('loginController', function ($scope, cache, user, userAddress) { $scope.user = user; $scope.userAddress = userAddress; caceh.set('user', user); caceh.set('userAddress', userAddress); }); //user myApp.service('user', function(cache) { //須要引用的時候 var userAddress = cache.get('userAddress'); //其餘代碼省略 });
代碼合併及壓縮
當功能模塊愈來愈多的時候,controller內就會有不少相似的代碼了,並且每增長一個js模塊,都須要在controller內註冊並添加到cache中去,實在是很麻煩。
其實你們應該已經發現了,只要咱們將模塊放在同一的文件夾內,而後經過掃描這個文件夾,並使用模板來進行代碼生成就能夠免去這些麻煩的註冊代碼了,代碼以下:
//模板 window.myApp= angular.module('myApp', []); myApp.controller('mainController', function ($scope, cache, <%= modules.join(', ') %>){ <% modules.forEach(function (m){ %> $scope.<%= m %> = <%= m %>; cache.set('<%= m %>', <%= m %>); <% }) %> }); <% codes.forEach(function (c){ %> <%- code %> <% }) %> //合併 var ejs = require('ejs'); var fs = require('fs'); var path = require('path'); var jsDir = 'js文件夾路徑'; var codes = []; var modules = []; fs.readdirSync(jsDir).forEach(function (filename) { if (filename.indexOf('.js') == -1) return; codes.push(fs.readFileSync(path.join(jsDir, filename), 'utf8')); modules.push(filename.replace('.js', '')); }); var tplCode = fs.readFileSync('模板路徑', 'utf8'); codes.unshift(ejs.render(tplCode, { modules: modules, codes: codes })); fs.writeFileSync('整合後的js文件路徑', codes.join('\r\n'), 'utf8');
這樣咱們即可以在js文件變化的時候,經過合併全部的js,可是這裏要注意將功能模塊的js和公用庫的js放在不一樣的文件夾下,引用公用代碼並不會去引用功能模塊,所以不須要加入到cache中去,並在合併的時候經過額外的代碼去拼接公用js。
經過以上的操做,咱們只須要在頁面上只引入一個js,這樣開發起來也會比較方便,可是測試的時候,就略微麻煩。
在這裏我建議將angularjs建立module和controller的生成代碼獨立放在一個生成模塊中,並生成一個js(如:config);將合併公用js和模塊js放在另外一個生成模塊中;並在項目中添加一個諸如development的變量來標識是否爲開發模式。
開發模式的時候,頁面上引用生成的config及其餘公用js和功能js;非開發者模式下,則引用合而且壓縮後的js,示例代碼以下:
<% var app = process.app; if (app.get('development')) { %> <script type="text/javascript" src="/js/config.js"></script> <script type="text/javascript" src="/js/lib/cache.js"></script> <script type="text/javascript" src="/js/main/user.js"></script> <script type="text/javascript" src="/js/main/userAddress.js"></script> <% } else { %> <script type="text/javascript" src="/js/myApp.min.js"></script> <% } %>
2個代碼生成的模塊代碼這裏就再也不寫出來了,所以大體的代碼上面都已經給出來了,其餘的就靠你們本身根據實際狀況去重構了,^_^。
壓縮js腳本的代碼也不寫了,具體的能夠查看文章開頭的UglifyJS2的示例代碼,須要注意的是except參數是不能少的,否則會將合併腳本內的angularjs的模塊名和功能模塊名替換成其餘的簡單變量,項目運行起來會出現錯誤。
結尾
因爲近段時間都是使用angualrjs配合nodejs來進行開發的,開發中遇到的問題和解決的方案整理了一下跟你們分享一下,但願對你們有所幫助。
大體的代碼基本上都有提供,其餘的就要靠你們本身去編碼了,這樣才能將分享的東西轉化成本身的。
今天的文章就到這裏了,若是有什麼錯誤、問題請留言給我,謝謝你們!