5. $watch list是有可能在最近一次迭代中被修改的表达式的集合。如果(model)发生了改变,那么$watch 函数会被调用,从而达到对特定的DOM重新赋值的目标。
6. 一旦Angular $digest loop 完成了(之前3提到的情况),离开angular和javascript的context后,浏览器紧跟着就会去重绘DOM,以响应变化。
下面解释例子“Hello Kitty”(-_-!)是如何在用户在文本框输入文本时实现数据绑定(data-binding)效果。
1. 编译阶段(compilation phase):
a) ng-model和input directive在<input>中版定keydown事件监听器。
b) {{name}}占位符(interpolation,不知道怎么翻译)(表达式)设置一个$watch以便在name发生改变时有所响应。
2. 执行阶段(runtime phase):
a) 在inut控件中按下”X”按钮,让浏览器触发一个keydown事件;
b) input directive捕捉到文本框值的改变,然后调用$apply(“name = ‘X';”),在angular execution context中更新应用的model。
c) Angluar将 “name = ‘X';”应用在model中。(model发生改变)
d) $digest loop开始
e) $watch list检测到name的值被改变了,然后再次解析{{name}}表达式,然后更新DOM。
f) Angulart退出(angular) execution context,再依次退出keydown事件以及javascript execution context;
g) 浏览器重绘视图,更新字符。
<!DOCTYPE html> <html lang="zh-cn" ng-app> <head> <meta charset="UTF-8"> <title>Hello Kitty!</title> <style type="text/css"> .ng-cloak { display: none; } </style> </head> <body> <input ng-model="name"/> <p>Hello {{name}}!</p> <script src="https://www.jb51.net/angular-1.0.1.js" type="text/javascript"></script> </body> </html>
四、Scope
scope的是负责检测model的变化,并作为表达式的执行上下文(execution context)。Scope是在一个类似于DOM结构的层次结构中嵌套的(据之前了解,划分可能跟controller有关)。(详情查看individual directive documentation,看看哪个directive会创建新的scope)
下面的例子展示”name”这个表达式的值是根据它依赖(所属)的scope决定的,而且还包含了值查找的方式(类似Js的作用域链,自己没有就找老爸要)。
<!DOCTYPE HTML> <html lang="zh-cn" ng-app> <head> <meta charset="UTF-8"> <title>scope</title> <style type="text/css"> .ng-cloak { display: none; } </style> </head> <body> <div ng-controller="ControllerA"> Hello {{name}}!; </div> <div ng-controller="ControllerB"> Hello {{name}}!; <div ng-controller="ControllerC"> Hello {{name}}!; <div ng-controller="ControllerD"> Hello {{name}}!; </div> </div> </div> <script src="https://www.jb51.net/angular-1.0.1.js" type="text/javascript"></script> <script type="text/javascript"> function ControllerA($scope) { $scope.name = 'Kitty'; } function ControllerB($scope) { $scope.name = 'Lcllao'; } function ControllerC($scope) { $scope.name = 'Jeffrey'; } function ControllerD($scope) { } </script> </body> </html>
五、Controller
<!DOCTYPE HTML> <html lang="zh-cn" ng-app> <head> <meta charset="UTF-8"> <title>Controller</title> <style type="text/css"> .ng-cloak { display: none; } </style> </head> <body> <div ng-controller="ControllerA"> Hello {{name}}! <button ng-click="doIt()">DoIt!!</button> </div> <script src="https://www.jb51.net/angular-1.0.1.js" type="text/javascript"></script> <script type="text/javascript"> function ControllerA($scope) { $scope.name = 'Kitty'; $scope.doIt = function() { $scope.name = "Handsome"; }; } </script> </body> </html>
Controller是在view背后的代码(-_-!)。它的职责是构建model,并通过回调函数,将其(model)推送到view中。View是当前scope到template(HTML)的映射(翻译得有点勉强...)。Scope是指挥model到view以及向controller发送event的纽带。
Controller与view分离是很重要的,因为:
1.Controller是写在javascript中的。Javascript是命令式的(imperative)。命令(imperative)是描述应用程序行为的一个好方法。Controller不应该包含任何显示信息(的逻辑)(DOM引用或者HTML片段)
2.View模版是写在HTML里的。HTML是声明式的。声明式(的HTML)是描述UI的好方法。View不应该包含任何行为。