1

I am trying to understand the $formatters and $parsers of NgModelController and with this excellent example

I have created this demo. But having few questions which needs to clear

Below is my main code

<body ng-app="app">
<input type="text" ng-model="what" placeholder="directive Value" custom-formatter>
<input type="text" ng-model="what" placeholder="model value" >
change value {{ what }}
</body>

and

angular
.module('app')
.directive('customFormatter', ['$timeout',function($timeout){
    return {
        require: 'ngModel',
        scope: {},
        restrict: 'A',
        link: function(scope, element, attrs, ngModelCtrl) {

           // format text going to user ( on view )
            ngModelCtrl.$formatters.push(function(modelValue){
                console.log('MV:' + modelValue);
                if (!modelValue)  return;
                else return modelValue.toUpperCase();
            });

            ngModelCtrl.$render = function () {
                console.log('render called');
                console.log(ngModelCtrl.$viewValue);
            };

            // scope.$watch('what', function() {
            //     console.log('watcher called');
            //       ngModelCtrl.$setViewValue({
            //           what: scope.what
            //       });
            // });

            ngModelCtrl.$parsers.push(function(viewValue){
                console.log('VV:');
                console.log(viewValue);
                if(!viewValue) return;
                else return viewValue.toLowerCase();
            });
        }
    };
}]);

my few confusion are below also with my understanding , Please correct me if I am wrong

  1. in my understanding for current scenario

something changes in scope value ( i.e. in ng-model with custom directive input box ) than it means viewValue changed

and if something changed in input box without custom directive but same ng-model , than that means as modelValue changed

is that right?

  1. When scope is set as isolated {} in custom directive then why changes reflects to other input box with same ng-model value

    Because we have added require:'ngModel' in custom directive?

is this right?

  1. When do we need to call $render? according to $render document

It is called when the view needs to be updated.

So tried

ngModelCtrl.$render = function () {
        console.log('render called');
        console.log(ngModelCtrl.$viewValue;) // this gives UPPERCASE text
};

But output (the other text box and {{ expression }}) doesn't show uppercase value :(

Do it need to call $setViewValue at it says

"Update the view value"

But how and where to call ? I tried

ngModelCtrl.$render = function () {
        console.log('render called');
        ngModelCtrl.$setViewValue({what : scope.what }) << doesn't work
        console.log(ngModelCtrl.$viewValue;) // this gives UPPERCASE text
};

also see the note inside special notebox saying

if you are calling $setViewValue for an input element, you should pass the input DOM value. It's also important to note that $setViewValue does not call $render or change the control's DOM value in any way. If we want to change the control's DOM value programmatically, we should update the ngModel scope expression. Its new value will be picked up by the model controller, which will run it through the $formatters, $render it to update the DOM.

I do not understand this much? what means by control and control's DOM

also see a line

"When used with standard inputs, the view value will always be a string"

but when I look in console inside $parsers => it is Object {what: undefined} is that the issue?

  1. tries with scope.$watch() but no output as UPPERCASE

     scope.$watch('what', function() {
        console.log('watcher called');
          ngModelCtrl.$setViewValue({
              what : scope.what
          });
     });
    

even this is never called , WHY so?

Please tell me when to use $watch and when to use $render with $viewValue and $setViewValue and how.

xkeshav
  • 53,360
  • 44
  • 177
  • 245

0 Answers0