绑定数据是怎样生效的

踩坑

  1. var app = angular.module("test", []);
  2. app.directive("myclick", function() {
  3. return function (scope, element, attr) {
  4. element.on("click", function() {
  5. scope.counter++;
  6. });
  7. };
  8. });
  9. app.controller("CounterCtrl", function($scope) {
  10. $scope.counter = 0;
  11. });
  12. <body ng-app="test">
  13. <div ng-controller="CounterCtrl">
  14. <button myclick>increase</button>
  15. <span ng-bind="counter"></span>
  16. </div>
  17. </body>
  18. //click后单次增1

看调试器,数据确实已经增加了,但界面没有跟着刷新。
但在**scope.counter++**后加上**scope.$digest();**就好了。


××××××××××××××××××××××××××××××××××××××**额外补充**×××××××××××××××××××××××××××××××××××××××
×××××××××××××××××××××××××××在没有angularJS的情况下实现此功能××××××××××××××××××××××××××××

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>two-way binding</title>
  6. </head>
  7. <body onload="init()">
  8. <button ng-click="inc">
  9. increase 1
  10. </button>
  11. <button ng-click="inc2">
  12. increase 2
  13. </button>
  14. <span style="color:red" ng-bind="counter"></span>
  15. <span style="color:blue" ng-bind="counter"></span>
  16. <span style="color:green" ng-bind="counter"></span>
  17. <script type="text/javascript">
  18. /* 数据模型区开始 */
  19. var counter = 0;
  20. function inc() {
  21. counter++;
  22. }
  23. function inc2() {
  24. counter+=2;
  25. }
  26. /* 数据模型区结束 */
  27. /* 绑定关系区开始 */
  28. function init() {
  29. bind();
  30. }
  31. function bind() {
  32. var list = document.querySelectorAll("[ng-click]");
  33. for (var i=0; i<list.length; i++) {
  34. list[i].onclick = (function(index) {
  35. return function() {
  36. window[list[index].getAttribute("ng-click")]();
  37. apply();
  38. };
  39. })(i);
  40. }
  41. }
  42. function apply() {
  43. var list = document.querySelectorAll("[ng-bind='counter']");
  44. for (var i=0; i<list.length; i++) {
  45. list[i].innerHTML = counter;
  46. }
  47. }
  48. /* 绑定关系区结束 */
  49. </script>
  50. </body>
  51. </html>


提示**:同一时间只允许一个$digest运行,当前的还没有走完就再次触发就会出错了。

$digest和$apply

差异

$apply可以接受一个函数,在应用数据之后,调用这个函数。

  1. var app = angular.module("test", []);
  2. app.directive("myclick", function() {
  3. return function (scope, element, attr) {
  4. element.on("click", function() {
  5. scope.counter++;
  6. scope.$apply(function() {
  7. scope.counter++;
  8. });
  9. });
  10. };
  11. });
  12. app.controller("CounterCtrl", function($scope) {
  13. $scope.counter = 0;
  14. });
  15. //click后单次增2

在简单的数据模型中,这两者没有本质差别,但是当有层次结构的时候,就不一样了。

  1. var app = angular.module("test", []);
  2. app.directive("increasea", function() {
  3. return function (scope, element, attr) {
  4. element.on("click", function() {
  5. scope.a++;
  6. scope.$digest();
  7. });
  8. };
  9. });
  10. app.directive("increaseb", function() {
  11. return function (scope, element, attr) {
  12. element.on("click", function() {
  13. scope.b++;
  14. scope.$digest(); //这个换成$apply即可
  15. });
  16. };
  17. });
  18. app.controller("OuterCtrl", ["$scope", function($scope) {
  19. $scope.a = 1;
  20. $scope.$watch("a", function(newVal) {
  21. console.log("a:" + newVal);
  22. });
  23. $scope.$on("test", function(evt) {
  24. $scope.a++;
  25. });
  26. }]);
  27. app.controller("InnerCtrl", ["$scope", function($scope) {
  28. $scope.b = 2;
  29. $scope.$watch("b", function(newVal) {
  30. console.log("b:" + newVal);
  31. $scope.$emit("test", newVal);
  32. });
  33. }]);
  1. <div ng-app="test">
  2. <div ng-controller="OuterCtrl">
  3. <div ng-controller="InnerCtrl">
  4. <button increaseb>increase b inner</button>
  5. <span ng-bind="b"></span>
  6. </div>
  7. <button increasea>increase a outer</button>
  8. <span ng-bind="a"></span>
  9. </div>
  10. </div>

$digest
刚刷新
image.png
点五次inner
image.png
点一次outer
image.png
再点一次outer
image.png
再点一次inner
image.png
总结**
inner正常更新,不受outer增加的影响,
但outer会监控inner增加,但不即时变化,只在下一次被点击时叠加inner的增长。

inner变化无法使outer即时更新。


$apply
刚刷新
image.png(当`scope.a=4`时,`a outer` 后的值为5)
点五次inner
image.png
点一次outer
image.png
再点一次outer
image.png
再点一次inner
image.png
总结**:
inner更新时outer联动更新,outer更新时inner不联动,
但inner在下次被点击时叠加outer的更新。
**

inner变化能使outer更新

当调用$digest的时候,只触发当前作用域和它的子作用域上的监控,
但是当调用$apply的时候,会触发作用域树上的所有监控。