在我们传统的web框架中,如Rails,Controller混合了来自model的数据并且糅合在模板里成为一个view呈现给用户。这种混合风格会导致single-way-view。视图只能反映在视图呈现的时候的model数据。当然也有写框架有望实现视图和模型的自动数据绑定。
AngularJs 采用了一种不同方式,即不是将数据混入模板然后替换Dom元素。AngularJs创建live模板作为视图。视图的独立组件被动态内插值替换,这个特征可能是AngularJs最重要的一个使得我们不用写一行JavaScript就完成了Hello world应用。
只需要包括Angularjs源到我们的html文件并且在Dom元素上设置一个ng-app特性就完成了一个应用。ng-app特性表面包含在特性之内的所有东西都属于这个Angularjs应用,这就是我们为什么能够嵌入一个Angular应用到另一个web app的缘由。
视图被修改就是变量被值替换,比如有一个name变量的值是soderberg,那么视图上“Hello {{name}}” 就返回“ Hello soderberg”。
数据的自动绑定机制给了我们映射视图和模型状态的能力,任何时候模型修改会直接反映到视图上无需写任何自定义js代码即能工作。是不是很神奇?
在MVC的世界里,控制器不必关注视图的混合呈现,这也本质上消除了分离view和controller逻辑的关注,使得代码可测试并令人愉快。
视图不需要知道如何保存对象-它只需要知道如何显示对象,同时,模型也不需要跟视图交互-它只需要包含处理视图的方法和数据,控制器的职责则是放置处理逻辑将视图和模型绑定。一旦Angularjs值可能发生改变,它就会调用$digest(),并且有一个dirty checking的过程,dirty checking是一种针对model发生变化检测的有效手机,每当值有变化,Angularjs就会在内部循环事件进行dirty check以保持所有的model状态一致。
简单数据绑定
回顾我们刚才写的代码,我们将name特性绑定到输入字段使用的是AngularJs的指令ng-model,它被包含在模型的对象里即$scope。这也就是说无论输入任何值都能直接反映到模型对象中。$scope对象就是一个javascript对象,有一些可用的属性用于视图和控制器的交互。
<!DOCTYPE html> <html ng-app> <head lang="en"> <meta charset="UTF-8"> <title>Simple app</title> <script src="https://cdn.bootcss.com/angular.js/1.2.6/angular.js"></script> <script src="HelloWorld.js"></script> </head> <body ng-controller="myController"> <input ng-model="person.name" type="text" placeholder="Your name"> <h1>{{clock}}</h1> </body> </html>
function myController($scope){ var updateClock=function() { $scope.clock=new Date(); } setInterval(function(){ $scope.$apply(updateClock); },1000); updateClock(); };
最好的数据绑定是我们能够使用javascript引用而非原始对象。clock改为clock.now,控制器代码如下:
function myController($scope){ $scope.clock={now:new Date()}; var updateClock=function() { $scope.clock.now=new Date(); } setInterval(function(){ $scope.$apply(updateClock); },1000); updateClock(); };