【问题标题】:AngularJS: re-apply formatter after parser has executedAngularJS:解析器执行后重新应用格式化程序
【发布时间】:2019-10-31 09:41:37
【问题描述】:

我在 AngularJS 应用程序中编写了一个自定义指令,并将其应用于文本输入。该指令定义了一个parser 将用户输入转换为数字。同时,该指令还定义了一个formatter,它解释模型中的数字并将其转换回文本输入以供显示。它看起来像这样:

qvangular.directive('mydirective', function ($filter) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            ngModelCtrl.$parsers.unshift(function(v) {
                return convertToNumber(v);
            });
            ngModelCtrl.$formatters.unshift(function(v) {
                return formatNumber(v);
            });
        }
    };
});

它有点工作,但我遇到的问题是:使用这种方法,格式化程序仅在数据模型最初绑定时运行(或当其值在代码中更改时),但当模型从用户输入。我希望格式化程序在用户更改输入后运行(并且输入已由解析器解释并应用于模型)。有办法吗?

编辑:一个实际的例子,以防提问者不清楚:

  1. 用户在文本框中输入“1K”
  2. 当文本框失去焦点时,解析器函数运行并调用convertToNumber("1K"),它将字符串转换为数字1000并返回
  3. 值1000 应用于模型
  4. 现在我想运行格式化函数,这样它就可以读取值1000 并将其转换为我想要显示的值,例如"1,000.00"

缺少第 4 步,我不知道如何强制 AngularJS “重新评估模型”,从而重新应用格式化程序。

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    一种常见的解决方案是绑定blur 事件并在那里格式化值:

    element.bind('blur', () => {
         let value = element.val();
         let formatted = formatNumber(value);    
         element.val(formatted);
    });
    

    【讨论】:

    • 谢谢,虽然这感觉有点“hacky”,但我会接受你的回答,如果没有人想出更好的东西,我明天会接受你的回答
    【解决方案2】:

    在我的输入掩码中,我实际上在解析器中重新渲染了模型的视图值:

    ngModelCtrl.$parsers.unshift(function(v) {
      ngModelCtrl.$setViewValue(formatNumber(v));
      ngModelCtrl.$render();
      return convertToNumber(v);
    });
    

    【讨论】:

    • 谢谢,这似乎是一个不那么“hacky”的解决方案
    猜你喜欢
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多