Angular Parser不会第二次触发

时间:2015-12-11 07:31:49

标签: angularjs

我有一个自定义指令,它接受类型文本的输入,格式化输入并且不允许用户键入字母表(仅限数字)。解析器可以正常处理小错误。如果我第一次尝试输入字母表它不允许我这是正确的,但第二次它允许我键入并且它不会触发解析器功能。有人可以告诉我我的错误在哪里吗?

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

演示:https://jsfiddle.net/t96fkuu7/5/

2 个答案:

答案 0 :(得分:1)

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

为此,您需要在模型控制器上手动设置$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
}

这是一个更新的工作示例:https://jsfiddle.net/17k7em04/

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

答案 1 :(得分:0)

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

所以而不是

elem.val($filter(attrs.format)(plainNumber));

检查是否有变化并告诉ngModelController开始......

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