angularJs闭包中使用$watch监听的执行过程

监听函数在定义之后不是就会立即执行一次吗,那为什么仍然不能显示呢,能解释一下具体的内部执行顺序吗?

<html ng-app="exampleApp">
<head>
    <title>Directives</title>
    <script src="angular.js"></script>
    <link href="bootstrap.css" rel="stylesheet" />
    <link href="bootstrap-theme.css" rel="stylesheet" />
    <script>
        angular.module("exampleApp", [])
            .directive("unorderedList", function () {
                return function (scope, element, attrs) {
                    var data = scope[attrs["unorderedList"]];
                    var propertyExpression = attrs["listProperty"];
                    if (angular.isArray(data)) {
                        var listElem = angular.element("<ul>");
                        element.append(listElem);
                        for (var i = 0; i < data.length; i++) {
                            var itemElement = angular.element('<li>');
                            listElem.append(itemElement);
                                var watcherFn = function (watchScope) {
                                    return watchScope.$eval(propertyExpression, data[i]);
                                }
                                scope.$watch(watcherFn, function (newValue, oldValue) {
                                    itemElement.text(newValue);
                                });
                        }
                    }
                }
            })
            .controller("defaultCtrl", function ($scope) {
                $scope.products = [
                    { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },
                    { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },
                    { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 }
                ];
                $scope.incrementPrices = function () {
                    for (var i = 0; i < $scope.products.length; i++) {
                        $scope.products[i].price++;
                    }
                }
            })
    </script>
</head>
<body ng-controller="defaultCtrl">
<div class="panel panel-default">
    <div class="panel-heading">
        <h3>Products</h3>
    </div>
    <div class="panel-body">
        <button class="btn btn-primary" ng-click="incrementPrices()">
            Change Prices
        </button>
    </div>
    <div class="panel-body">
        <div unordered-list="products" list-property="price | currency"></div>
    </div>
</div>
</body>
</html>

clipboard.png

阅读 2.5k
1 个回答

你可以试一下下面这段代码的执行结果就知道自己的问题在哪里了,这是js中的一个很典型的闭包问题,可以使用匿名函数解决.

for(var i = 0;i<3;i++){
    setTimeout(function(){
      console.log(i);
    }, 200);
};
for(var j = 0;j<3;j++){
    (function (j) {
      setTimeout(function(){
        console.log('j',j);
      }, 200)
    })(j);
};

你所监听的一直是data[3],可以修改如下:

     (function(i,itemElement){
        var watcherFn = function (watchScope) {
            return watchScope.$eval(propertyExpression, data[i]);
        }

        scope.$watch(watcherFn, function (newValue, oldValue) {
            itemElement.text(newValue);
        }); 
    })(i,itemElement)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题