我可以使用ngModelController的$ formatter来完全控制输入字段的呈现方式吗?

时间:2013-10-22 07:48:46

标签: angularjs

我正在尝试创建一个模拟type="number"的输入,但我想添加自己的按钮。基本上我已经做了

<form name="fasdf">
    <button class="btn" ng-click="decrement()">&#9668;</button>
    <input type="text" ng-model="model" display-as-number />
    <button class="btn" ng-click="increment()">&#9658;</button>
</form>

我正在使用input type="text",因为我不希望用户代理将其自己的按钮添加到该字段中。

应该可以使用input本身输入值以及使用按钮递增或递减值。

angular.module('app',[])
.controller('Ctrl', ['$scope', function($scope) {

  $scope.model = 0;

  $scope.decrement = function() {
    $scope.model--;
  };

  $scope.increment = function() {
    $scope.model++;
  };

}])

该值最初是0,但是当用户开始输入文本时,我希望在键入时删除任何前导零(嗯,实际上西装想要这样但是你得到了我的漂移)。

我的理论是我可以使用$formatter和/或$parser通过制作访问ngModelController的指令来执行此操作。

angular.module('app')
.directive('displayAsNumber', [function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, controller) {

        controller.$formatters.push(function (modelValue) {
            var value = parseInt(modelValue, 10);
            return value;
        });

        controller.$parsers.push(function (viewValue) {
            var value = parseInt(viewValue, 10);
            return value;
        });          
    };
}]);

但是每当我在输入中键入内容时运行$formatter,它就不会覆盖输入字段的实际值,换句话说它不会剥离任何前导零。

我可以通过侦听DOM事件来实现这一点(尽管我不能通过用

替换指令体来改变每个键盘上的值,因为它会将光标移动到字段的末尾)
element.on('focus', function() {
  var value = parseInt(element.val(), 10);
  if (value === 0)
    element.val('');
});

element.on('focusout', function() {
  if ('' === element.val().trim())
    element.val(0);
  else
    element.val(parseInt(element.val(), 10));
});

结果行为足够好(如果值为0,则会在焦点上消隐,并在焦点处消除前导0s

问题是,如果不向element添加事件监听器,我有什么方法可以实现此行为? 如何使用ngModelController正确控制输入的呈现方式?

Plnkr:http://plnkr.co/edit/YOkFGNGamfA1Xb9pOP1U?p=preview

1 个答案:

答案 0 :(得分:3)

所以,是的,在看了其他新问题之后我看到了this并意识到我只是错过了对controller.$render()

的电话
controller.$parsers.push(function (viewValue) {
  var value = parseInt(viewValue, 10);
  controller.$viewValue = value;
  controller.$render();
  return value;
});

解决了我的问题。我现在就走了。