Angular在模板中评估2次表达式,为什么?

时间:2014-09-16 12:43:50

标签: angularjs

我希望你们能帮助我。看看这个简短的代码。

<!DOCTYPE html>
<html ng-app="testApp">
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.js"></script>
        <script type="text/javascript">
            angular.module('testApp', [])
            .controller('testController', ['$scope', function ($scope) {
                $scope.greetMe = function(){
                    console.log('I\'ve been called')
                    return 'Greetings'
                };
            }]);
        </script>
    </head>
    <body>
        <div id="mainWrapper" data-ng-controller="testController">
            {{greetMe()}}
        </div>
    </body>
</html>

也位于:http://plnkr.co/edit/K9fgNWcsm5gDvOfB19y6

如果你在浏览器中运行它(我试过chrome和firefox),你的控制台会显示
(2) I've been called.

我用角度1.0.1,1.2.0和1.3.0 rc.0

尝试了这个

当我在一个更大的应用程序的控制器中添加类似的console.log时,我发现了这种行为,我正在尝试构建它。 我非常震惊,因为在我的实际案例中,表达式被评估了6次甚至更糟,所有属性及其所有孩子的孩子也被一遍又一遍地调用/执行。在我的特定情况下,似乎每个$ http.get()调用都会触发一个新的评估轮次。

为什么?我可以阻止吗?

2 个答案:

答案 0 :(得分:1)

这是因为角度脏检查。通常我们应该避免在不需要时从模板调用函数。当角度完成此功能的执行时,会自动调用角度摘要,它会检查所有模型的值以进行同步。然而,角度不知道是否有任何模型在您的函数内部发生变化,因此角度调用再次起作用并检查是否有任何当前范围的模型正在更新,然后它会将该值同步到您的模板。

答案 1 :(得分:1)

这实际上是AngularJS如何使用其$ digest()循环。 https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope#$消化

您可能不应该在Angular Expressions中调用方法来从范围中获取值。

它应该在控制器中看起来像这样:

$scope.greeting = 'not greeted yet';

$scope.greet = function() {
    $scope.greeting = 'Greetings!!!';
};

而且你要么用手按钮来打电话:

<button ng-click="greet()">greet me</button>

或者,如果您需要初始化的内容,您可以直接在控制器中执行此操作:

$scope.greeting = 'not greeted yet';

请参阅此编辑的Plunker:http://plnkr.co/edit/pG34sk5KryrphosVJFVB?p=preview