Angularjs 角度分析器不';不要第二次触发

Angularjs 角度分析器不';不要第二次触发,angularjs,Angularjs,我有一个自定义指令,它接受文本类型的输入,格式化输入,并且不允许用户键入字母表(仅限数字)。若我第一次尝试输入字母表,它不允许我输入正确的字母,但第二次它允许我输入,并且不会触发解析器函数。谁能告诉我哪里出了错 ctrl.$formatters.unshift(function (a) { return $filter(attrs.format)(ctrl.$modelValue) }); ctrl.$parsers.unshift(function (

我有一个自定义指令,它接受文本类型的输入,格式化输入,并且不允许用户键入字母表(仅限数字)。若我第一次尝试输入字母表,它不允许我输入正确的字母,但第二次它允许我输入,并且不会触发解析器函数。谁能告诉我哪里出了错

ctrl.$formatters.unshift(function (a) {
            return $filter(attrs.format)(ctrl.$modelValue)
        });
 ctrl.$parsers.unshift(function (viewValue) {
            var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');
            elem.val($filter(attrs.format)(plainNumber));
            return plainNumber;
        });

演示:。

在解析器中,不要直接访问元素-让ngModelController为您完成工作

所以不是

elem.val($filter(attrs.format)(plainNumber));
检查是否有更改,并告诉ngModelController开始

if (plainNumber != viewValue) {
   ctrl.$setViewValue(plainNumber);
   ctrl.$render();
}

将模型的DOM值格式化为用户输入文本的重点是ngModelController的
$parsers
,即当通过DOM更改输入时viewValue将通过的管道

// in your directive's link function
ctrl.$parsers.unshift(function (viewValue) {
  var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');

  ctrl.$viewValue = $filter('number')(plainNumber);
  ctrl.$render();

  // return the modelValue
  return plainNumber
}
为此,您需要在模型控制器上手动设置
$viewValue
属性,并调用
$render
更新DOM

// in your directive's link function
ctrl.$parsers.unshift(function (viewValue) {
  var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');

  ctrl.$viewValue = $filter('number')(plainNumber);
  ctrl.$render();

  // return the modelValue
  return plainNumber
}
下面是一个更新的工作示例:


注意:您不应该从
$parsers
中调用
$setViewValue
,因为它调用$parsers函数,所以在早期版本的angular中会导致无限循环

谢谢你的建议。我可以使用ngModelController,但如果我需要访问$setViewValue,它有一个数组,其中有一个元素,我使用ngModelController[0],这对我来说似乎很奇怪。你能告诉我为什么我有数组吗?JSFIDLE是你真正的代码吗?如果没有-张贴你的真实代码。。。因为我用你的小提琴试过了,它肯定有用:明白我真正的代码是什么意思吗?小提琴工作正常,但如果你尝试我提到的场景,你可以复制错误。你尝试过我在评论中链接的小提琴吗?没有看到,对此表示抱歉。我试试看。非常感谢你