为什么$ watch in angular js导致console.log输出两次?

时间:2013-08-01 18:29:17

标签: javascript angularjs

这是我的代码:

<!doctype html>
<html lang="en-US" ng-app>
    <!--Head-->
    <head>
        <meta charset="UTF-8">
        <title>Lesson 5 - ng-show & ng-hide</title>
        <meta name="viewport" content="width=device-width">
        <style type="text/css">
            * {
                box-sizing: border-box;
            }
            body {
                font: 16px/1.5 Consolas;
                color: #222;
                margin: 5em;
            }
        </style>
    </head>
    <!--Body-->
    <body>

        <div ng-controller="information">
            <!--Input-->
            <label for="name">
                Name:
                <input type="text" name="username" id="username" placeholder="Your name here please" ng-model="name"/>
            </label>
            <br>
            <label>
                Hide?
                <input type="checkbox" ng-model="checked"/>
            </label>
            <!--Div that is hidden-->
            <div ng-hide="checked">
                Hidden Message here
                <br>
                Welcome {{ name || "user" }}!
            </div>

        </div>
        <script type="text/javascript" src="angular_1.0.7.js"></script>
        <script type="text/javascript">
            var information = function ($scope) {
                $scope.$watch(function () {
                    console.log($scope.name);
                });
            };
        </script>
    </body>
</html>

如果您运行此命令并更改<input>标记内的值,那么您将在控制台窗口中看到,每次更改值时,您输入的值都会输出两次,如下图所示:

enter image description here

为什么会这样?

1 个答案:

答案 0 :(得分:7)

每个digest cycle多次调用手表:

  

$ digest循环不断迭代直到模型稳定,这意味着$ evalAsync队列为空,$ watch列表没有检测到任何变化。

当您键入一个字符时,Angular会进入摘要循环(因为Angular会自动添加一个事件监听器,因为您正在使用ng-model)并检测到更改。然后它再次通过循环 以确保没有其他更改。这样做是因为如果一个$ watch触发,它可能会改变一些其他监视属性,然后需要检测它,这样才能执行监视功能。