使用ngModel的自定义字符分隔符无法正常工作

时间:2017-01-18 06:56:29

标签: angularjs-directive angular-ngmodel

我想在文本框中使用AngularJs中的字符分隔符格式化输入的数字。

我已经创建了一个指令来进行格式化。该指令正在生成正确的输出,但无法正确更新ngModel

<input type="text" data-ng-model="aadhaar" dashsep="'-'">

.directive('dashsep', function($timeout) {
  'use strict';
  return {
    restrict: 'A',
    scope: {
        dashsep: '=',
        ngModel: '=ngModel'
    },
    require: '?ngModel',
    link: function(scope, element, attr) {
        element.bind("keyup", function (event) {
            var formattedAdh = "";
            //console.log(element.val());

            var test = element.val().toString();

            for(var i=0;i<=test.length-1;i++){
                //console.log(test[i]);
                if(i%4 === 0 && i>0){
                    formattedAdh+= scope.dashsep;
                }
                formattedAdh += test[i];
            }

            // Following script is not updateing the ngModel/textbox with the formatted value properly //
            /*
                //element.val(scope.$eval(formattedAdh));
                // OR
                //scope.ngModel = formattedAdh;
            */

            // Following output is showing proper value IF ABOVE SCRIPT IS COMMENTED //
            console.clear();
            console.log(formattedAdh);
        });
     }
   };
 });

Plunker中提供了完整脚本。

1 个答案:

答案 0 :(得分:0)

根据我对示例代码的理解,我认为您尝试在每4个字符后添加一个破折号。也就是说,当用户键入&#34; aaaabbbbcccc&#34;时,您期望&#34; aaaa-bbbb-cccc&#34;显示在input[text]和范围模型中以进行相应更新。

鉴于此假设,您将要使用格式化的视图值调用$setViewValue,而不是直接更新范围模型表达式。这很重要,因为$setViewValue会在更新范围模型表达式之前将您的新视图值与ngModelController的内部视图值和内部模型值同步。

假设新范围模型已成功更改 - 即,它传递解析器和验证程序,则$viewChangeListeners将运行。从那里,您可以调用$render以使用新的视图值更新DOM。

此处plunker有变化。

link: function(scope, element, attr, ngModelController) {
    element.on('keyup', function (event) {
      var viewValue = element.val().toString();

      // add a dash every 4 characters
      if ((viewValue.length + 1) % 5 === 0) {
        viewValue += scope.dashsep;
      }

      // angular updates the internal view value, internal model, then scope model based on DOM
      ngModelController.$setViewValue(viewValue, event);
    });


    ngModelController.$viewChangeListeners.push(function(){
      console.log(ngModelController.$modelValue);
      // when model changes, call $render to display the latest view value
      ngModelController.$render();
    });
})

如果您希望获得有关ngModelController的更深入说明,请参阅本文:https://medium.com/product-at-catalant-technologies/i-have-to-relearn-angulars-form-api-every-time-i-use-it-83287c521968#.f5hle083e