20

The code is simple:

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <script>document.write("<base href=\"" + document.location + "\" />");</script>
  <link rel="stylesheet" href="style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
</head>
<body ng-controller="MainCtrl">
  Hello {{name()}}!
</body>
</html>
<script>
var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name= function() {
    console.log("---name---:" + new Date());
    return "Freewind";
  };
});

</script>

You can see there is a name function and we invoke it in the body only one time. But in the console, it prints twice of ---name---::

---name---:Wed Feb 20 2013 14:38:12 GMT+0800 (中国标准时间)
---name---:Wed Feb 20 2013 14:38:12 GMT+0800 (中国标准时间)

You can see a live demo here: http://plnkr.co/edit/tb8RpnBJZaJ73V73QISC?p=preview

Why the function name() has been invoked two times?

2
  • it is very difficult sometimes to get to the exact question you are looking for. Thx for this! Commented Jun 22, 2014 at 15:55
  • 1
    Though you can restrict it to call only once by using init variable ref: plnkr.co/edit/l57V2rzX51JumtAtWXBN?p=preview hope this helps. Commented Sep 9, 2016 at 9:45

1 Answer 1

42

In AngularJS, anything wrapped in double curly braces is an expression that gets evaluated at least once during the digest cycle.

AngularJS works by running the digest cycle continuously until nothing has changed. That's how it ensures the view is up-to-date. Since you called a function, it's running it once to get a value and then a second time to see that nothing has changed. On the next digest cycle, it will run at least once again.

It's generally a good idea to only call idempotent methods (like name) from the template for this very reason.

Sign up to request clarification or add additional context in comments.

12 Comments

+1, also to make it clear: angularjs may call any function bound in the view at any point during digest phase and multiple digest phases might be executed. It makes no guarantee about the number of calls.
Right! The only thing guaranteed is that it will run at least once.
@desbo You can manually maintain a scope variable, which is usually the preferred approach if the method performs any computation; the controller then changes the scope variable as necessary (manually or through watches). But the reason your Plunker doesn't work is that count is assigned, not referenced. Demo of both: plnkr.co/edit/miXH6b6HsRWwDNKVgiPP?p=preview
That can depend upon particulars. In general, I place services on scopes that represent things, but I do not place any services on the scope that represent actions. That is, a userService would not go on the scope, but a currentUser would. This is a compromise for separation of concerns. I will note, however, that there is some disagreement here as to the best practice.
@saurabh: I agree with using variables instead of functions for all but trivial things. However, it does not prevent the expression from being evaluated more than once. Whatever is within the curly braces will be evaluated twice. If it's a function, it will be called twice, but if it's a variable, its value will still be pulled twice - because something else in the cycle could have changed it.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.