AngularJS是由Misko Hevery 和 Adam Abrons 两个人共同创建的,在2009年卖给了Google,它是一个构建动态Web应用的一个Javascript框架,目的是为了克服HTML在构建Web应用程序上的不足而设计的。
1) MVC
2) 模块化
3)指令系统
4)双向数据绑定
其中指令系统和双向数据绑定是AngularJS特有的,主要区别于其他的前端MVC框架,如BackBone
MVC是在1979年由Trygve Reenskaug第一次提出
Model:数据模型层
View:视图层,负责展示,一般我们能在页面上看到的都是
Controller:业务逻辑和控制逻辑
MVC的好处是职责很清晰,代码模块化,下面我们来看一段代码
<!DOCTYPE html> <html ng-app="MyAngular"> <head> <meta charset="UTF-8"> <title>AngularJS MVC</title> </head> <body> <div ng-controller="HelloAngular"> <p>{{greeting.text}}, AngularJS</p> </div> </body> <script src="js/angular-1.4.6.min.js"></script> <script> angular.module('MyAngular', []) .controller('HelloAngular', function($scope){ $scope.greeting = { text: 'Hello' } }) </script> </html>
从上面代码可以看出,在html标签里,使用ng-app定义了AngularJS的管理边界,也就是说,AngularJS可以管理整个html。
在body中的div里面定义了ng-controller,这就是MVC中的控制器,也就是C,而整个p标签就是我们的视图层,也就是V。
在最下面的script里,我们首先定义了一个AngularJS的模块MyAngular,然后在这个模块上定了控制器HelloAngular,里面的text:'Hello',就是我们的M层。
其实在上面的代码中,我们已经使用了AngularJS的模块化,下面我们来用另外一种方式来重写上面的JS代码部分
var myModule = angular.module('MyAngular', []); //定义模块 myModule.controller('HelloAngular', ['$scope', //在模块上定义一个控制器方法helloAngular function helloAngular($scope) { $scope.greeting = { text: 'Hello' } } ]);
上面第一排的代码为我们定义了一个模块myModel,然后我们利用该模块的controller方法生成一个控制器。请注意,我们在定义controller控制器时,第一个参数是控制器名称,而第二个是在一个方括号里,方括号里的第一个成员是一个变量$scope,第二个成员是一个Function,这个Function的参数也叫$scope,也就是说,这里的代码告诉Angular,请把第一个成员$scope注入到下面的方法中,这里也体现了Angular的依赖注入特性。
下面我们用一张图来说明下AngularJS的模块化
在AngularJS中,一切都是从模块开始的,创建了模块,我们就可以在这个模块上调用各种方法,如Filter、Directive、Controller等。
首先我们来看下下面的代码
<!DOCTYPE html> <html ng-app="MyModule"> <head> <meta charset="utf-8" /> <title>AngularJS - 指令系统</title> </head> <body> <hello></hello> </body> <script src="js/angular-1.4.6.min.js"></script> <script> var MyModule = angular.module('MyModule', []); MyModule.directive('hello', function(){ return { restrict: 'E', template: '<div>Hi Everyone!</div>', replace: true } }); </script> </html>
上面的HTML代码中,我们可以看到<hello></hello>这样的标签,但是在HTML里,没有定义这杨的标签,浏览器引擎是不认识它的,这时,浏览器会忽略掉这个标签,Angular怎么做呢?在下面的JS代码中,Angular在已定义的模块MyModule上,使用了directive方法,在这个方法中,第一个参数就定义了hello这个标识符,用来说明在HTML中,hello标签的意义,在返回的属性中有一个template,它的作用就是说明这个标签会显示什么样的内容。
目前大多数的前端框架都是单向数据绑定,如jQueryUI、Backbone、Flex等。单向数据绑定是怎么做的呢?一般的做法是我们先生成模板(template),然后从后台获取数据(Model),通过绑定机制,将模板和数据结合起来生成HTML标签插入到文档流中(View)。
这样的单向数据绑定有什么问题吗?如果我们的数据有变化,那么按照这种流程,我们不得不重新将模板和新的数据再次生成HTML插入到文档流中,也就是需要重构HMTL页面。
那么AngularJS中的双向数据绑定又是怎么回事呢?
双向数据绑定认为,视图和数据是对应的,借助事件机制,当视图发生变化时,数据模型也会发生相应的变化,而当数据模型发生变化时,视图会自动更新,这种场景应用最典型的就是我们的表单,当用户在表单中完成输入后,数据模型就会立刻拿到用户输入,下面我们用一段代码来说明下
<!DOCTYPE html> <html ng-app> <head> <meta charset="utf-8"> </head> <body> <div> <input type="text" ng-model="greeting.text"> <p>{{greeting.text}}, AngularJS</p> </div> </body> <script src="js/angular-1.4.6.min.js"></script> </html>
当我们在表单中任意输入后,下面的p标签会马上显示出用户输入,代码中的双大括号( {{}} )表示一个取值表达式。