Javascript 试图在指令中访问$modelValue时未定义它

Javascript 试图在指令中访问$modelValue时未定义它,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我正在尝试实现一个英寸到毫米的转换器。。。我想要的是,如果用户在文本框中输入以英寸为单位的值,则文本框(视图)应以英寸为单位显示值。其中,模型应保持以mm为单位的值。为此,我编写了如下所示的指令 模型在mm中得到更新,我已经通过调试进行了检查。 但是,当我在文本框外单击(模糊事件),将视图切换到web应用程序中的其他选项卡并返回时,模型值将再次填充到文本框中。所以我认为在焦点事件中,我可以将$modelValue/25(毫米到英寸的转换)作为参数传递给$setViewValue()函数。但我得到

我正在尝试实现一个英寸到毫米的转换器。。。我想要的是,如果用户在文本框中输入以英寸为单位的值,则文本框(视图)应以英寸为单位显示值。其中,模型应保持以mm为单位的值。为此,我编写了如下所示的指令

模型在mm中得到更新,我已经通过调试进行了检查。 但是,当我在文本框外单击(模糊事件),将视图切换到web应用程序中的其他选项卡并返回时,模型值将再次填充到文本框中。所以我认为在焦点事件中,我可以将$modelValue/25(毫米到英寸的转换)作为参数传递给$setViewValue()函数。但我得到$modelValue属性为未定义

.directive('metricImperialInput', function($timeout){
              return{
                  require: 'ngModel',
                  link: function(scope, element, attrs, modelCtrl){
                      element.bind("focus", function(e) {
                      $timeout(function() {
                          modelCtrl.$setViewValue(modelCtrl.$modelValue/25);
                          modelCtrl.$render();
                     }, 0);
                   });
                      modelCtrl.$parsers.push(function(inputValue){
                          var changedOutput = parseInt(inputValue) * 25;
                          modelCtrl.$setViewValue(parseInt(inputValue));
                          modelCtrl.$render();
                          return parseInt(changedOutput);
                      });
                  }
              };
          });

您正在尝试访问输入焦点上的模型值。相反,尝试在keyup上访问模型值。还可以使用modelCtrl.$viewValue代替modelCtrl.$modelValue。工作示例如下:

    `element.bind("keyup", function(e) {
            $timeout(function() {
                    modelCtrl.$setViewValue(modelCtrl.$viewValue/25);
                    modelCtrl.$render();
             }, 0);
    });`

您正确地使用了
ngModelController.$parsers
,但在解析器内部您也使用了
$setViewValue()
,这是完全不需要的,因为解析器函数接收的输入值已经是
$viewValue
!因此,可以将其与
$render()
一起删除。焦点事件也是不必要的,因为如果您正确使用$parsers,它不会做任何有用的事情

现在您只剩下以下内容:

.directive('metricImperialInput', function($timeout){
          return{
              require: 'ngModel',
              link: function(scope, element, attrs, modelCtrl){
                modelCtrl.$parsers.push(function(inputValue){
                  var changedOutput = parseInt(inputValue) * 25;
                  return parseInt(changedOutput) || 0;
                });
              }
          };
      });
但这有一个问题,初始$modelValue在您开始使用输入之前不会被转换。为此,我添加了以下几行,以确保当指令加载时,它将正确设置初始值,然后解析器处理所有事情

var initVal = $parse(attrs.ngModel)(scope);
modelCtrl.$viewValue = initVal / 25;
modelCtrl.$modelValue = initVal;
modelCtrl.$render();
你可以在这里找到完整的解决方案