0

My index.php

<!doctype html>
<html lang="en" ng-app="abc">
<head>
    <meta charset="utf-8">
    <title>Google Phone Gallery</title>
    <base href="" />
</head>
<body>

    <div ng-controller="test">
        {{sayhello()}}
    </div>


</body>
<script src="js/core/angular.min.js"></script>
<script src="js/modules/example/controllers/controller.js"></script>
</html>

My controller.js:

var app = angular.module('abc', []);

app.factory('greeter', function($rootScope){
    return{
        greet: function(){
            alert('run');
        }
    }
});
app.controller('test', function($scope, greeter){
    $scope.sayhello = function(){
        greeter.greet();
    }
});

Can you guys tell me, why my alert ran twice?

But if I change:

<div ng-controller="test">
    {{sayhello()}}
</div>

To:

<div ng-controller="test">
    <input type="button" value="Click 2 run" ng-click="sayhello()">
</div>

It runs only once? Can you guys tell me how?

Graipher
  • 6,891
  • 27
  • 47
AHSR0x
  • 3
  • 1
  • 1

2 Answers2

0

It is by design.

All angular expressions including the interpolation string {{sayhello()}} and those in $watch() will be re-evaluated repeatedly (for each $digest cycle), to detect changes in model and update views accordingly.

Even an empty $watch() will behave the same, see #1305 for a discussion.

If you would like to understand more on how the databinding of angularjs and its digest cycle works, read this post:

How does data binding work in AngularJS?

Community
  • 1
  • 1
runTarm
  • 11,537
  • 1
  • 37
  • 37
0

What you're seeing is how Angular's digest cycle works. It will keep evaluating expressions that the view is bound to until nothing has changed. This means it has to evaluate the binding at least twice. In this case, both times the expression evaluated to undefined, and the digest cycle stops.

To only evaluate it once, assign the value to a property on the scope...

<div ng-controller="test">
    {{greeting}}
</div>

app.controller('test', function($scope, greeter){
    $scope.sayhello = function(){
        greeter.greet();
    };
    $scope.greeting = $scope.sayhello();
});

Fiddle

Anthony Chu
  • 37,170
  • 10
  • 81
  • 71