浅谈AngularJS

入手AngularJS已经有半年了,确实让我学习了不少东西。于是想记录一些关于这个框架的东西,希望道友少走点儿弯路。如果中间有什么错误的希望能够帮忙指出来,本人将不胜感激。本篇主要说说Angular的主要特点。

适合项目的才是最好的。

我对这话深信不疑,入门前端以来,我一直都对技术抱着敬畏之心。确实,一个技术的产生就是很多思维的碰撞,能够让别人获益匪浅,这才是技术的魅力。在AngularJS的学习过程中,确实让我学习了很多,普通的jQuery函数式编程到Angular的声明式编程。不只是思维的转变还有代码风格的转变。虽然在使用过程中有过磕磕绊绊,但我最终还能够乐道其中。这里面不光是Angular带给我的技术知识和对项目开发效率的提高,更重要的是代码组织,往高点说就是前端架构。虽然现在我的技术还谈不上什么前端架构,但我相信,这条路我会慢慢探寻下去。

下面简单谈谈Angular的一些特点。

双向数据绑定



毫无疑问,双向数据绑定是Angular的一大特性,算是它的一大的优点。使用双向数据绑定能够很快的编写代码。看看下面的例子:
1
2
3
4
5
6
7
8
9
10
11
<form>
<div class="form-group">
<label>输入内容:label>
<input type="text" class="form-control" ng-model="inputData" />
div>
<div class="form-group">
<label>您输入的是:label>
<p ng-bind="inputData">p>
<p>{{inputData}}p>
div>
form>

浅谈AngularJS

这是一段HTML内容,使用ng-model来对输入框进行数据绑定,绑定值为inputData。然后使用ng-bind的方式将值显示在页面中。而实现这个功能的JS代码很少很少。只需要声明一下应用模块就行了,注意模块名app与html标签的ng-app对应。

1
var app = angular.module('app', []);

如此简单的就完成了动态输入显示的功能,这在以前的普通jQuery代码中是不可想象的。而在真实的项目中,双向数据绑定能极大的减少我们的代码量,开发效率大大提高。

Angular的双向数据绑定功能是它的优点,同时也有它的弊端。Angular建议一个页面最多2000个双向绑定,但在实际项目中一个页面通常很容易超标。而Angular的数据监听越多性能就越差,解决方案是使用 bindonce,参考链接:https://github.com/Pasvaz/bindonce。来进行单向数据绑定,对于那些只需要单向绑定的就使用它,以此来提高性能。

指令



强大的指令功能为我们开发带来了极大的便利。自定义标签,组件化。下面是一个简单的自定义指令my-progress,进度条。样式使用的是Bootstrap。

HTML结构:

1
2
3
4
5
6
7
<my-progress percent="60">my-progress>

<my-progress percent="40" type="info">my-progress>

<my-progress percent="10" type="warning">my-progress>

<div my-progress percent="99" type="danger">div>

JavaScript代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
angular.module('app', [])
.directive('myProgress', function(){
return {
restrict: 'EA',
replace: true,
scope: {
type: '@',
percent: '='
},
template: [
'
',
'
{{percent}}%',
'
'
,

'
'

].join('')
}
});

效果预览:

浅谈AngularJS

在HTML代码中的my-progress就是自定义的指令。这个的指令directive代码中定义了restrict参数为EA,它代表的意思是可以使用标签的形式和属性的形式来书写指令。

我们可以看到,使用指令的方式HTML代码看上去更加简洁了,而且可扩展性也好。非前端人员一看代码也能大致看出功能和意思。这样极大的提高了多人协作,减少了沟通成本,开发效率自然就高了。在以后的文章中我可能会详细讲解Angular指令的内容。

模块化



Angular在模块化方面做得很好。angular.module是定义Angular模块的方法,组成模块的整体包括:controllerdirectivefilterservicefactory等。这在大型项目中是很好的架构方式,以此解决项目中代码过多,模块依赖等问题。

定义模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
var app = angular.module('app', []);

app.controller('myController', function(){
//code here...
});

app.directive('myDirective', function(){
//code here...
});

app.service('myFactory', function(){
//code here...
});

其中angular.module方法第一个参数是个模块名称,第二个参数是一个依赖数组,就是当前模块依赖哪些其它模块。一般可以将一个模块分成多个文件,例如:directive.js、service.js、filter.js等,之后可以通过代码压缩合并的方式组合在一起。如果代码文件过大,还可以考虑模块化加载的方式,在github上已经有了很多的模块化加载解决方案。

依赖注入



Angular的依赖注入很棒,能够很好的解决组件和代码的复用率,以及测试。使用依赖注入不会造成代码的全局污染。它提供了多种注入方式。

value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var app = angular.module('app', []);

app.value("settings", {
name: 'APP',
ui: 'bootstrap'
});

app.controller('controllerName', ['$scope', 'settings', function($scope, settings){
console.log(settings);

$scope.name = settings.name;
}]);

app.directive('directiveName', ['settings', function(settings){
//code here...
}]);

使用value可以定义一个值,对象,数组。然后使用的时候可以在controllerdirectivefactory等中使用。需要注意的是,在使用的时候如果更改其值,那么所有的使用都会影响。它是可以被修改的。而且还有一点就是value不可在config里注入

constant常量

constantvalue类似,不过它不能被修改可以在config里注入
1
2
3
4
5
6
7
var app = angular.module('app', []);

app.constant('constantData', 'value');

app.config(['constantData', function(constantData){
//code here...
}]);

factory工厂

factory是用于返回函数的值。它根据需求创造值,每当一个服务或控制器需要。它通常使用一个工厂函数来计算并返回对应值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var app = angular.module('app', []);

app.factory('myFactory', function(){
var settings = {};

var myFactory = function(name, value){
if(value){
return settings[name] = value;
}else{
return settings[name];
}
};

return myFactory;
});

provider提供者

provider提供者所使用的AngularJS内部创建过程中配置阶段的service服务,factory工厂等。提供者是一个特殊的工厂方法以及get方法,用来返回值/服务/工厂。
1
2
3
4
5
6
7
8
9
10
11
var app = angular.module('app', []);

app.config(function($provide) {
$provide.provider('myProvider', function() {
this.$get = function() {
var obj = {};

return obj;
};
});
});

service服务

服务是一个单一的JavaScript包含了一组函数对象来执行某些任务。服务使用service函数,然后注入到控制器的定义。
1
2
3
4
5
6
7
var app = angular.module('app', []);

app.service('myService', function(){
this.calc = function(a, b){
return a + b;
};
});

路由



Angular本身自带路由模块ngRoute,而在真实的项目中推荐使用更加强大的ui-router来构建前端路由。下表列出了ngRoute与ui-router的区别:

ngRouteui-router
应用程序中的url应用程序内的一个区域
只是平面层次结构可以嵌套的层次结构
名称只能是url名称可以自定义
只能通过url导航通过名称或 url 导航
只能单一视图ng-view可以存在多个视图ui-view
只能填充一个视图可以填充任何视图
通过指令将填充某一部件通过状态填充某一部件

参考文档:https://github.com/angular-ui/ui-router

小结



Angular的使用为开发带来了很大的便利,当然它的优点远不止上面这些。而缺点呢?当然也有。使用Angular框架,项目代码组织必须按照它的代码规范来写,很受拘束。没有一个框架是万能的,总之记住那句话:适合项目的才是最好的。源码可以到我的 github 上查看。感谢道友阅读!