A function called multiple times from a template

In my template, I have something like this:

{{formatMyDate(date)}}

      

but date

- this is a scope variable that is not immediately available, so this expression will call the function formatMyDate()

multiple times (returning undefined

) before returning the correct value.

I could check if it is not date

invalidated in the function, but I think it would be cleaner NOT to call the function at all if date

- null

.

Any way to achieve this? Can a custom filter help me here?

EDIT:
It has been suggested that this behavior may be normal, depending on the $ digest cycle.
Then I put scope.$watch

to check how many times the value changes date

.
Note that I am defining them in a directive.

scope.$watch('date', function(value){
  console.log('watched_date: ' + value)
})

      

and I also added console.log () to my function formatMyDate

scope.formatMyDate = function(date){
  console.log("called_date: " + date)
  return dateService.format(date, 'YYYY-MM-DD')
}

      

Console check I am getting (pseudocode)

called_date: undefined
watched_date: undefined
called_date: undefined // many many times (around 20/30)
called_date: correctValue //2 or 3 times 
watched_date: correctValue 
called_date: correctValue //other 3/4 times

      

I am wondering if this is still loop related $digest

or if this is a bug in my code

+2


source to share


2 answers


I would recommend that you do something differently:

Use a date$filter

or if you are doing something VERY unique and the date is $filter

not enough for you, then you can create your own $filter

, for example:

app.filter('formatMyDate', function () {
    return function (date) {
        if (!date) return "";
        var result;
        //your code here    
        return result;
    };
});

      

And use it like in your template:

{{date | formatMyDate}}

      



UPDATE:

I guess I didn't quite answer your question, I just gave you advice on how to improve the code. This time I'll try to answer your question:

The $ digest loop is where Angular ensures that the model settings are changed so that it can render the view with the updated changes. To do this, Angular runs a loop in which each iteration evaluates all the expressions in the view template as well as the function's $watcher

functions $scope

. If in the current iteration the result is the same as the previous one, then Angular will exit the loop. Otherwise, it will try again. If after 10 attempts everything is not settled, Angular will exit with an error: "Infite $ digest Loop Error" (infdig) .

So, the first time the loop $digest

is executed, all expressions are evaluated (at least) twice. And then every time you make changes to $scope

, or one $watcher

of the $scope

runs, the cycle $digest

starts again, to make sure that everything is settled, so your expression will be evaluated again. This is how Angular does "data binding", this is normal behavior.

So in your case, when in your template you do this: {{formatMyDate(date)}}

or this one {{date | formatMyDate}}

, you define Angular expressions that will be evaluated every time the loop is $digest

run, which, as you can imagine, very often. Therefore, it is very important to make sure that $filters

(or the functions) you use in your view are efficient and inactive.

+7


source


You can do it:

{{date && formatMyDate(date)}}

      



will only execute the second case if the first condition exists and is nonzero and undefined.

Check out this fiddle: http://jsfiddle.net/HB7LU/7512/

+1


source







All Articles