Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When ngModel's $render is called in AngularJS?

In this official example, what is the following code doing?

// model -> view ctrl.$render = function() {   elm.html(ctrl.$viewValue); }; 

As far as I can see, $render is never called.

When $render is actually called?


UPDATE

Looks like $render is called every time the model changes. But, it is not called when the model gets its initial value. Is there a way to control the rendering of the initial value?

like image 543
Misha Moroshko Avatar asked Jan 13 '14 03:01

Misha Moroshko


People also ask

Where is ngModel defined?

ngModel is a directive which binds input, select and textarea, and stores the required user value in a variable and we can use that variable whenever we require that value. It also is used during validations in a form. We can use ngModel with: input. text.

What is the purpose of ngModel?

The ng-model directive binds the value of HTML controls (input, select, text-area) to application data. It is a part of the FormsModule. This directive is used by itself or as part of a larger form. It accepts a domain model as an optional Input.

What does :: mean in AngularJS?

:: is used for one-time binding. The expression will stop recalculating once they are stable, i.e. after the first digest.

What is $viewValue in AngularJS?

$viewValue is the current value in the view - your string input.


1 Answers

Right $render is called by Angular when a model changes. According to the $render docs:

$render()

Called when the view needs to be updated. It is expected that the user of the ng-model directive will implement this method.

It's helpful to see how $render is called in ngModelWatch (which is called whenever an ngModel changes). Here we see $formatters called, then the $viewValue updated, and finally $render is called:

$scope.$watch(function ngModelWatch() {     var value = ngModelGet($scope);      // if scope model value and ngModel value are out of sync     if (ctrl.$modelValue !== value) {        var formatters = ctrl.$formatters,           idx = formatters.length;        ctrl.$modelValue = value;       while(idx--) {         value = formatters[idx](value);       }        if (ctrl.$viewValue !== value) {         ctrl.$viewValue = value;         ctrl.$render();       }     }      return value;   }); }]; 

The reason it's not called for the initial value is because of this line at the end of the directive:

// load init value from DOM ctrl.$setViewValue(elm.html()); 

That manually updates the view value without triggering ngModelWatch() and therefore without going through $formatters or $render. If that line was instead:

scope.content=elm.html(); 

You'd see $render called by Angular as that would trigger a $watch

like image 195
KayakDave Avatar answered Sep 19 '22 10:09

KayakDave