技术干货利用AngularJS开发复杂web应用

Posted 新乐视云联

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了技术干货利用AngularJS开发复杂web应用相关的知识,希望对你有一定的参考价值。

引言

传统的jQuery的前端项目虽然大大的简化了DOM操作,但仍然存在如下问题:


1. 代码结构耦合性太高,模块化程度低;

2. 缺乏依赖注入机制;

3. 频繁的DOM操作,代码过于臃肿。


前端MVC框架的出现则很好的解决了jQuery项目带来的问题。当前前端MVC框架越来越火热,越来越多的公司开始放弃传统的jQuery,而转向MVC框架,如AngularJS,backbone等。在众多前端MVC框架中,谷歌出身的AngularJS算是佼佼者。


乐视云前端团队在2015年开始使用AngularJS来构建新项目。迄今为止已经成功的将云主机移植到了AngularJS版本上。下面讲述构建基于AngularJS的项目时遇到的问题和经验。



 云主机前端架构简介


根据angular提供的控制器,过滤器,视图,等概念我们将前端结构划分如下。


【技术干货】利用AngularJS开发复杂web应用


Router用来实现页面的路由功能,是页面的分发入口。AngularJS可以使用Router替换页面中的局部显示。将公共的菜单,导航条与具体页面分离出来达到页面部分的复用。


Coludvm是云主机相关的具体代码。根据AngularJS的MVC结构,分为控制器和视图模板两部分,控制器是AngularJS程序的核心部分,所有的业务逻辑都应该放在这里,控制器绑定的数据则以模板的形式放在前端页面中,view和Template都是存放视图模板的地方,区别是view里存的是页面模板,Template里存放的是对话框模板。


Common是项目的公共模块,模块里三部分,filter,service,directive都是AngularJS提供的用于模块化开发的三个功能,filter是数据过滤器,可用于基本的数据显示格式化,直接在模板中使用,service是服务模块,提供了公共功能的封装,如HTTP请求,消息提示框,URL配置获取等。directive是AngularJS的一个特色,它一般封装了对DOM的一些操作,因为好的实践中不能在控制器中直接操作DOM,这些作用在DOM上的指令大大增强了普通DOM的功能,通过对DOM的操作封装了一些项目通用的控件。以上划分只能满足基本的功能开发,实际中经常需要引用第三方的插件,AngularJS满足了我们这方面的需求,AngularJS提供了相当丰富的插件库,使用简单,可以作为AngularJS的一个模块集成到AngularJS项目中。尽管AngularJS使用方便,架构清晰,但使用中还是遇到了各种问题。


 项目遇到的问题和采用的解决方案


1
控制器代码膨胀

虽然开始阶段遵循了控制器里不要操作DOM这一铁则,但随着项目进展,代码愈发复杂,控制器也越来越臃肿。AngularJS的依赖机制很好的解决了这个问题,数据的格式化和数据过滤应全部放在filter中,和项目有关的数据映射应该提取出来,减少switch分支映射代码,做到源数据只有一份,衍生数据和格式全部脱离源数据。其中的一些配置数据则可以放在服务里,如在云主机项目中,Config服务模块存放了配置相关的信息,任何想使用它的地方只要引用Config依赖就可以了。总之写代码时要注意区分当前代码性质和归属。


2
HTTP状态返回错误问题

后台会返回三种状态:

(1) 表示成功,需要把数据返回给controller;

(2) 表示登录超时,需要刷新页面跳转到登录页面;

(3) 表示后台错误,需要把错误信息提示给用户。


我们想要在全局的地方对这些逻辑进行了统一处理,但因为向后端的请求都是$http实现的,无法对返回的数据进行拦截处理。后来通过在HttpService中对$http用promise进行了一层装饰,在装饰中添加了我们的逻辑,解决了这个问题。


3
表单中文输入问题

AngularJS表单中输入中文时会有乱码问题,项目中使用的是utf8编码,但后台传递的数据是加密过的unicode十进制编码,在非AngularJS程序的页面中是可以正常解析显示的,但AngularJS中却不能正常解析。这个问题有两种解决办法,如果只是显示不编辑,可以用ng-bind-html指令解决。但这样做的缺点是无法在表单中编辑中文信息,而且ng-bind-html是AngularJS的扩展模块,使用时需要额外引用AngularJS扩展文件,增加了带宽负担。我们采用的做法是直接针对unicode十进制编码转码,以下是unicode十进制编码转utf8的代码片段。


【技术干货】利用AngularJS开发复杂web应用


由于AngularJS自身的BUG,一些指令使用中存在一些需要注意的问题,这些BUG出现的毫无道理,也没有明确的解释原因。只能使用时可以避开和采用一些hack写法。最常见的问题就是ng-if使用问题,很多奇怪的BUG都是源于这个指令使用,我们的经验是如果遇到了奇怪的BUG,首先考虑用ng-show替换ng-if。ng-if这个指令会产生很多问题,甚至影响到其他AngularJS插件。


 前端组件库


除了上述问题解决方案,AngularJS中一个重点部分就是前端组件库。前端组件库能够极大的提高代码的可复用率和开发的效率。AngularJS中使用指令封装一些可复用的功能操作,指令可以被用来创建自定义的HTML标签,这些标签可以用作新的自定义的控件。它们也可以用来"渲染"有一定行为的元素,也可以以一些有趣的方式来操作DOM属性。一个指令就是一个能引入新语法的东西。把分离的组件组合成一个组件,这种创建应用的方式将使得添加、修改和删除页面功能变得异常简单。指令是AngularJS的一个非常强大且独有的特性。前端组件库能够极大的提高代码的可复用率和开发的效率。 


AngularJS通过directive能够很好的实现组件开发。我们把项目中多次用到的UI组件封装在了指令中,在使用时,简单添加一个属性就能实现相当复杂的功能。

【技术干货】利用AngularJS开发复杂web应用

【技术干货】利用AngularJS开发复杂web应用


 【技术干货】利用AngularJS开发复杂web应用

【技术干货】利用AngularJS开发复杂web应用


 前端自动化工具与单元测试

1
前端自动化工具

接下来的部分介绍我们项目中的前端工具与单元测试。前端自动化工具,主要用来负责上线前脚本的合并,压缩,给脚本添加版本号,以及线上环境和测试环境的配置切换。我们采用了gulp来做我们的自动化工具,主要是考虑到gulp丰富的插件,可以帮助我们基本的功能,例如js压缩我们用的gulp-uglify,给脚本添加版本号用的是gulp-rev,而且基于gulp我们还可以做一些自定义的开发,例如RequireJS模块的压缩我们用的是r.js,在自动化处理的入口处我们使用RequireJS提供的r.js进行第一步的压缩处理, 利用RequireJS的文件依赖关系和自定义的config文件配置进行压缩合并。我们通过gulp可以把RequireJS模块合并集成到框架中,使自动化工具能够满足我们的一些特定需求。


【技术干货】利用AngularJS开发复杂web应用

2
前端单元测试框架

因为AngularJS本身是通过依赖注入的方式的来实现模块的依赖关系的,因此可以很方便的分模块的编写单元测试的用例。我们的单元测试框架是基于karma和jasmine来实现的。

【技术干货】利用AngularJS开发复杂web应用



开发环境的前后端分离的架构


最后说一下我们开发环境中的前后端分离的架构。为什么要前后端分离,原因有三:


1. 前后端代码耦合在一块不方便单独的部署;

2. 前后的IDE不太一样,后端服务配置实在太过复杂;

3. 前端需要自己的一套自动化工具,单元测试框架。


我们使用了Node.js作为前后端分离的中间代理,对于浏览器发出的静态资源请求和api数据请求作出分发,这样前端代码完全脱离后端服务项目,而后端服务只提供api数据。




展望


目前云主机项目基于AngularJS解决了传统jQuery项目中存在的模块化开发相关问题。通过指令封装了自己的ui库,做到了高度复用。从jQuery到AngularJS,我们迈出了一大步,未来我们计划开发一些通用的ui接口,不只是在AngularJS框架下使用,通过配置改变和任何项目达到无缝连接。


彩蛋
技术干货可定制啦!


看了这么多乐视云的技术分享,你还想get√ 哪方面的技术干货?参与下方投票(可多选,也可单独微信留言)乐视云团队将根据大家关注的方向带来更多精彩的技术干货!


点击右下方“写留言”,告诉乐视云你想要的技术干货!

以上是关于技术干货利用AngularJS开发复杂web应用的主要内容,如果未能解决你的问题,请参考以下文章

如何利用angularjs打造一款简单web应用

图书Ionic实战:基于AngularJS的移动混合应用开发

利用前端MVC框架AngularJS实践设计模式

前端干货|9 种改善 AngularJS 性能的方法

angularjs主要是做啥

AngularJS介绍