另类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来进行开发的,开发中遇到的问题和解决的方案整理了一下跟你们分享一下,但愿对你们有所帮助。

  大体的代码基本上都有提供,其余的就要靠你们本身去编码了,这样才能将分享的东西转化成本身的。

  今天的文章就到这里了,若是有什么错误、问题请留言给我,谢谢你们!

相关文章
相关标签/搜索