回顾

  上一篇文章主要讲解了创建兼容任意浏览器(主要是ie的一些奇葩问题)的angularjs web应用,但是项目开发中其实更重要的还是在功能的模块化、代码自动压缩上面,这样项目在后期维护或者功能的重复利用上才会更方便,那么今天主要围绕以下几个主题来讲讲如何在不是用其他js模块化库的情况下,开发便于管理的angualrjs模块化代码:

  • 使用service来创建模块
  • 模块间引用
  • 代码合并及压缩

  本文中的代码均已nodejs来实现。

  nodejs中,使用UglifyJS2来实现代码压缩

使用service来创建模块

  以前创建angualrjs应用都是直接基于对scope的直接绑定来完成的,例如:登录功能,代码如下:

//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模块化库会带来一些问题,而且效果也不尽人意,代码也会变得很复杂。

  鉴于以上的一些问题,我不得不寻找一些其他的方案来替代,于是后来就想到了使用service来替代模块化(可能是资质比较差的原因吧),这样便可以充分利用angularjs的特性来完成,首先创建一个user的service,其实就是将当前scope内的代码迁移到user.js内,代码如下:

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来进行开发的,开发中遇到的问题和解决的方案整理了一下跟大家分享一下,希望对大家有所帮助。

  大致的代码基本上都有提供,其他的就要靠大家自己去编码了,这样才能将分享的东西转化成自己的。

  今天的文章就到这里了,如果有什么错误、问题请留言给我,谢谢大家!

另类angularjs应用的更多相关文章

  1. AngularJS - 服务简介

    服务是AngularJS中非常重要的一个概念,虽然我们有了控制器,但考虑到其生命实在脆弱,我们需要用到服务. 起初用service时,我便把service和factory()理所当然地关联起来了. 确 ...

  2. AngularJS重型前端框架

    一.AngularJs AngularJs是一种前端的重型框架,而现在正在被Aue.js所取代.而Aue的和AngularJs大同小异. AngularJs核心功能有MVC.模块化.自动化双向数据绑定 ...

  3. 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇

    什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...

  4. AngularJs之九(ending......)

    今天继续angularJs,但也是最后一篇关于它的了,基础部分差不多也就这些,后续有机会再写它的提升部分. 今天要写的也是一个基础的选择列表: 一:使用ng-options,数组进行循环. <d ...

  5. AngularJS过滤器filter-保留小数,小数点-$filter

    AngularJS      保留小数 默认是保留3位 固定的套路是 {{deom | number:4}} 意思就是保留小数点 的后四位 在渲染页面的时候 加入这儿个代码 用来精确浮点数,指定小数点 ...

  6. Angular企业级开发(1)-AngularJS简介

    AngularJS介绍 AngularJS是一个功能完善的JavaScript前端框架,同时是基于MVC(Model-View-Controller理念的框架,使用它能够高效的开发桌面web app和 ...

  7. 模拟AngularJS之依赖注入

    一.概述 AngularJS有一经典之处就是依赖注入,对于什么是依赖注入,熟悉spring的同学应该都非常了解了,但,对于前端而言,还是比较新颖的. 依赖注入,简而言之,就是解除硬编码,达到解偶的目的 ...

  8. 步入angularjs directive(指令)--点击按钮加入loading状态

    今天我终于鼓起勇气写自己的博客了,激动与害怕并存,希望大家能多多批评指导,如果能够帮助大家,也希望大家点个赞!! 用angularjs 工作也有段时间了,总体感觉最有挑战性的还是指令,因为没有指令的a ...

  9. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

随机推荐

  1. VR快速发展下,从业者如何把握机会?

      美国科技博客VentureBeat周末刊登赛斯·沙赫纳(Seth Schachner)的文章,分析了在虚拟现实快速发展的情况下,业内所面临的机会,以及如何把握这些机会.   沙赫纳是资深的数字战略 ...

  2. JS 日期格式化和解析工具

    本来想模仿Java里面的SimpleDateFormat()对象的,但是感觉这样用起来不方便,所以还是直接写成单独的方法算了. 原文链接 日期格式化 使用说明 formatDate(date, fmt ...

  3. 【系统移植】kernel分析

    内核启动流程 第二阶段 starte_kernel: | rest_init:  |  kernel_init   |   do_basic_setup(); // 加载驱动    |    do_i ...

  4. CAS 实现单点登录 .NET MVC

    单点登录 Single Sign On,简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 单点登录原理 ...

  5. 接入多家ERP厂商,美团点评餐饮高速路开启

    前段时间美团点评CEO王兴所提出的中国互联网进入下半场观点引发了互联网从业人士以及网友们的热议.当时王兴提出,当前国内外所有的互联网公司包括美团点评在内都还远没有做好整个产业链的服务,美团点评也只做了 ...

  6. Jenkins + GitHub + fir-cli 一行命令从源码到fir.im

    上周简书作者宣X_x  分享了一篇文章--用Jenkins+GitHub+Xcode+fir搭了一个持续集成环境,整个记录见(传送门). _______ 其实fir.im为我们提供了一个更简单的方式: ...

  7. iOS-多线程-内存管理

    iOS与OSX 多线程和内存管理  总结 一.              自动引用计数 1.自动引用计数(ARC)就是指内存管理中对引用采用自动计数的技术. 满足以下条件即可使用这种功能: Xcode ...

  8. FIREDAC操作SQLITE内存数据库

    SQLite不仅可以把数据库放在硬盘上,还可以放在内存中,经测试,同样条件下数据库放在内存中比放在硬盘上插入记录速度快差不多3倍. 但数据库放在内存中时有如下缺陷: 1.断电或程序崩溃后数据库就会消失 ...

  9. 学习Git

    参考廖雪峰老师的个人网站:http://www.liaoxuefeng.com 版本库初始化 通过git init命令将这个命令变为git可以管理的仓库 添加文件 用命令git add file告诉G ...

  10. hive函数 -- split 字符串分割函数

    hive字符串分割函数 split(str, regex) - Splits str around occurances that match regexTime taken: 0.769 secon ...