1

我试图理解NgModelController的$formatters$parsers以及这个优秀的例子

我创建了这个演示。但是有几个问题需要澄清

下面是我的主要代码

<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>

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();
            });
        }
    };
}]);

我的一些困惑也在我的理解之下,如果我错了,请纠正我

  1. 根据我对当前情况的理解

范围值的某些变化(即在具有自定义指令输入框的 ng-model 中)比这意味着viewValue发生了变化

并且如果在没有自定义指令但相同的 ng-model 的情况下在输入框中发生了某些更改,则这意味着modelValue更改了

那正确吗?

  1. 当范围{}在自定义指令中设置为隔离时,为什么更改会反映到具有相同ng-model值 的其他输入框

    因为我们require:'ngModel' 在自定义指令中添加了?

这是正确的吗?

  1. 我们什么时候需要调用$render?根据$render 文件

当需要更新视图时调用它。

所以试过

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

但输出(另一个文本框和 {{ 表达式 }})不显示大写值:(

需要打电话吗$setViewValue

“更新视图值”

但是如何以及在哪里打电话?我试过了

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

还可以看到特殊笔记本里面的注释说

如果您为输入元素调用 $setViewValue,则应传递输入 DOM 值。同样重要的是要注意 $setViewValue 不会调用 $render 或以任何方式更改控件的 DOM 值。如果我们想以编程方式更改控件的 DOM 值,我们应该更新 ngModel 范围表达式。它的新值将由模型控制器获取,它将通过 $formatters 运行它,$render 它以更新 DOM。

我不是很明白吗?控制控制的DOM是什么意思

也看到一条线

“与标准输入一起使用时,视图值将始终为字符串”

但是当我在 $parsers => 中查看控制台时,这是Object {what: undefined} 问题所在吗?

  1. 尝试scope.$watch()但没有输出为大写

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

即使这从未被调用,为什么会这样?

请告诉我何时使用$watch以及何时使用$render$viewValue$setViewValue以及如何使用。

4

0 回答 0