另類angularjs應用

回顧javascript

  上一篇文章主要講解了建立兼容任意瀏覽器(主要是ie的一些奇葩問題)的angularjs web應用,可是項目開發中其實更重要的仍是在功能的模塊化、代碼自動壓縮上面,這樣項目在後期維護或者功能的重複利用上纔會更方便,那麼今天主要圍繞如下幾個主題來說講如何在不是用其餘js模塊化庫的狀況下,開發便於管理的angualrjs模塊化代碼:html

  • 使用service來建立模塊
  • 模塊間引用
  • 代碼合併及壓縮

  本文中的代碼均已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來進行開發的,開發中遇到的問題和解決的方案整理了一下跟你們分享一下,但願對你們有所幫助。

  大體的代碼基本上都有提供,其餘的就要靠你們本身去編碼了,這樣才能將分享的東西轉化成本身的。

  今天的文章就到這裏了,若是有什麼錯誤、問題請留言給我,謝謝你們!

相關文章
相關標籤/搜索