我必须绕过ngModelController。$解析器来存储一个值

时间:2016-03-18 18:50:39

标签: javascript jquery angularjs

我刚开了一个bug report about how ngModelController.$parsers does not work on Chrome, Safari, or FireFox。但是,我正在处理的应用程序提示输入错误报告仍然是一个正在进行的项目,我需要找到一个解决方法。

由于该错误,以下代码 无效。此代码使用jQuery Masked Input以及Angular 1.5:

link: function (scope, element, attrs, ctrl) {
    // Build mask.
    var mask = '99999?-9999';
    $(element).mask(mask);

    // Store all zip codes without non-digit characters
    // E.G.: 12345-6789 -> 123456789
    //       12345 -> 12345
    ctrl.$parsers.unshift(function (viewValue) {
        var nonDigitCharacters = /[^0-9]/g;
        var digitsOnly = viewValue.replace(nonDigitCharacters, '');

        return digitsOnly;
    });

    ctrl.$formatters.push(function (value) {
        return $filter('zip')(value, false);
    });
}

但是,我真的不知道如何在不使用$viewValue函数的情况下将当前ngModelController.$parser应用于模型。我正在考虑做这样的事情:

$(element).on('keyup', function () {
    var nonDigitCharacters = /[^0-9]/g,
        digitsOnly = ctrl.$viewValue.replace(nonDigitCharacters, '');

    // Something with digitsOnly?
});

......作为一种临时解决方法,但我不知道到底要做什么。

问题:从指令直接将值应用于模型有哪些选项?

1 个答案:

答案 0 :(得分:0)

我发现了一个解决方法。差不多......你必须蛮力这种事。

幕后的ngModelController.$parsers几乎是以下列表:

  1. 通过读取元素的值获取当前$viewvalue
  2. $viewValue传递到当前的$parser函数
  3. 获取$parser函数的结果;将它传递给下一个。
  4. 重复完成。
  5. 直接将所有$parser函数的结果应用于模型。
  6. ......差不多,我必须手动复制,如下所示:

    $(element).on('keyup', function() {
        ctrl.$setViewValue($(element).val());
        var nonDigitCharacters = /[^0-9]/g,
            digitsOnly = ctrl.$viewValue.replace(nonDigitCharacters, '');
    
        var model = $parse(attrs.ngModel),
            modelSetter = model.assign;
    
        scope.$apply(function () {
            modelSetter(scope, digitsOnly);
        });
    });
    

    这样做可以让你直接绕过ngModelController.$parsers。话虽如此,我不确定是否有任何我想知道的细微之处需要注意。希望这可以让我度过难关,直到找到bug并找到更好的解决方法,或修复Angular团队管理的bug。