绑定数据是怎样生效的
踩坑
var app = angular.module("test", []);app.directive("myclick", function() {return function (scope, element, attr) {element.on("click", function() {scope.counter++;});};});app.controller("CounterCtrl", function($scope) {$scope.counter = 0;});<body ng-app="test"><div ng-controller="CounterCtrl"><button myclick>increase</button><span ng-bind="counter"></span></div></body>//click后单次增1
看调试器,数据确实已经增加了,但界面没有跟着刷新。
但在**scope.counter++**后加上**scope.$digest();**就好了。
××××××××××××××××××××××××××××××××××××××**额外补充**×××××××××××××××××××××××××××××××××××××××
×××××××××××××××××××××××××××在没有angularJS的情况下实现此功能××××××××××××××××××××××××××××
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>two-way binding</title></head><body onload="init()"><button ng-click="inc">increase 1</button><button ng-click="inc2">increase 2</button><span style="color:red" ng-bind="counter"></span><span style="color:blue" ng-bind="counter"></span><span style="color:green" ng-bind="counter"></span><script type="text/javascript">/* 数据模型区开始 */var counter = 0;function inc() {counter++;}function inc2() {counter+=2;}/* 数据模型区结束 *//* 绑定关系区开始 */function init() {bind();}function bind() {var list = document.querySelectorAll("[ng-click]");for (var i=0; i<list.length; i++) {list[i].onclick = (function(index) {return function() {window[list[index].getAttribute("ng-click")]();apply();};})(i);}}function apply() {var list = document.querySelectorAll("[ng-bind='counter']");for (var i=0; i<list.length; i++) {list[i].innerHTML = counter;}}/* 绑定关系区结束 */</script></body></html>
提示**:同一时间只允许一个$digest运行,当前的还没有走完就再次触发就会出错了。
$digest和$apply
差异
$apply可以接受一个函数,在应用数据之后,调用这个函数。
var app = angular.module("test", []);app.directive("myclick", function() {return function (scope, element, attr) {element.on("click", function() {scope.counter++;scope.$apply(function() {scope.counter++;});});};});app.controller("CounterCtrl", function($scope) {$scope.counter = 0;});//click后单次增2
在简单的数据模型中,这两者没有本质差别,但是当有层次结构的时候,就不一样了。
var app = angular.module("test", []);app.directive("increasea", function() {return function (scope, element, attr) {element.on("click", function() {scope.a++;scope.$digest();});};});app.directive("increaseb", function() {return function (scope, element, attr) {element.on("click", function() {scope.b++;scope.$digest(); //这个换成$apply即可});};});app.controller("OuterCtrl", ["$scope", function($scope) {$scope.a = 1;$scope.$watch("a", function(newVal) {console.log("a:" + newVal);});$scope.$on("test", function(evt) {$scope.a++;});}]);app.controller("InnerCtrl", ["$scope", function($scope) {$scope.b = 2;$scope.$watch("b", function(newVal) {console.log("b:" + newVal);$scope.$emit("test", newVal);});}]);
<div ng-app="test"><div ng-controller="OuterCtrl"><div ng-controller="InnerCtrl"><button increaseb>increase b inner</button><span ng-bind="b"></span></div><button increasea>increase a outer</button><span ng-bind="a"></span></div></div>
$digest
刚刷新
点五次inner
点一次outer
再点一次outer
再点一次inner
总结**:
inner正常更新,不受outer增加的影响,
但outer会监控inner增加,但不即时变化,只在下一次被点击时叠加inner的增长。
inner变化无法使outer即时更新。
$apply
刚刷新
(当`scope.a=4`时,`a outer` 后的值为5)
点五次inner
点一次outer
再点一次outer
再点一次inner
总结**:
inner更新时outer联动更新,outer更新时inner不联动,
但inner在下次被点击时叠加outer的更新。
**
inner变化能使outer更新
当调用$digest的时候,只触发当前作用域和它的子作用域上的监控,
但是当调用$apply的时候,会触发作用域树上的所有监控。
