$ parsers和$ formatters只被调用一次,而不是每次更新值

时间:2016-12-21 08:19:18

标签: javascript angularjs ecmascript-5

我尝试创建一个名为currency的指令,该指令在输入中的文本之前附加$。美元符号应始终显示,不应该删除。

这是我的代码:

app.directive('currency', function() {
    return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, elem, attrs, controller) {

      // view -> model
      controller.$parsers.push(function (viewValue) {
        viewValue = viewValue.replace(/^\$/, '');
        controller.$viewValue = viewValue;
        return viewValue;
      });

      // model -> view
      controller.$formatters.push(function (modelValue) {
        modelValue = '$' + modelValue;
        controller.$modelValue = modelValue;
        return modelValue;
      });
    }
  };
});

工作示例:https://jsfiddle.net/U3pVM/29012/

如您所见,美元符号最初会附加,但可以删除,之后不会附加。似乎我推送到$formatters的函数只被调用一次。是应该像那样工作还是我错过了什么?我该如何实现所需的行为?

2 个答案:

答案 0 :(得分:2)

好的,我尝试了一种解决方法,它可以工作,但我不确定这是否是正确的方法。

更新小提琴:https://jsfiddle.net/U3pVM/29014/

controller.$parsers.push(function (viewValue) {
      //console.log(viewValue.substring(0,1));

      if(viewValue.substring(0,1) != "$"){
            var view_value = "$" + viewValue;
          controller.$setViewValue(view_value);
          controller.$render();
      }
        viewValue = viewValue.replace(/^\$/, '');
        //controller.$viewValue = viewValue;


        console.log(viewValue);
        return viewValue;
      });

P.S:我不确定您为什么在ngModel函数中注入controller link。这可能是个错误。

答案 1 :(得分:2)

我认为你不太了解$ parsers和$ formatters的作用。每当您在输入字段中输入内容时,$ parsers都负责将此值转换为模型值。格式化程序负责将模型值转换为输入字段中的显示值。

当您有人在字段中输入内容时,您尝试做的是更改输入字段($ formatter功能)的内容($ parser功能)。

虽然我确信有一些变通方法可以让它以这种方式工作,但是当你这样做时,你会误用$ parsers和$ formatters的概念。相反,您应该查看自定义指令(或扩展您拥有的指令)以添加到执行您尝试执行的操作的输入,例如通过处理密钥。

修改

请参阅以下代码示例,了解链接函数,以便您了解我的意思:

link: function (scope, elem, attrs, controller) {

  elem.bind('keyup', function(evt) {
     // Change the displayed value after every keypress
     // This function is an example and needs serious work...
     // Perhaps you should even put this in a separate directive
     var value = elem.val().replace(/[^$0-9]/g, '');
     if (value && value.substring(0,1) !== '$') {
        value = '$' + value;
     }
     elem.val(value);
  });

  // view -> model
  controller.$parsers.push(function (viewValue) {
    // Any time the view changes, remove the $ sign and interpret the rest as number for the model
    var modelValue = viewValue.replace(/^\$/, '');
    return parseFloat(modelValue);
  });

  // model -> view
  controller.$formatters.push(function (modelValue) {
    // Any time the model (number) changes, append it with a $ sign for the view
    var viewValue = '$' + modelValue;
    return viewValue;
  });
}

或检查整个小提琴:https://jsfiddle.net/cL0hpvp4/