When ngModel's $render is called in AngularJS?

31,389

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

Share:
31,389

Related videos on Youtube

Misha Moroshko
Author by

Misha Moroshko

I build products that make humans happier. Previously Front End engineer at Facebook. Now, reimagining live experiences at https://muso.live

Updated on January 13, 2020

Comments

  • Misha Moroshko
    Misha Moroshko over 4 years

    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?

  • Misha Moroshko
    Misha Moroshko over 10 years
    Thanks for the detailed explanation! Could you explain please why in this example $render is not called when the model changes?