AngularJS - 设置模型属性不更新输入文本(数字验证)

时间:2012-09-07 23:10:37

标签: angularjs

看看这个小提琴:http://jsfiddle.net/bwjbz/6/

我正在努力严格执行积极的整数。我尝试了几种途径,似乎无法得到我正在寻找的东西。 (如果您尝试了几次,最终可能会在输入中输入非数字或负数。)

除了上述小提琴,我还尝试使用数字过滤器,并尝试创建自己的指令。

号码过滤器:

<input type="number" min="0" max="1000" value="{{itm.qty | number:0}}" required data-ng-model="itm.qty" data-ng-change="setQty()" data-whole-number>

你会注意到data-whole-number指令。我对指令还不太满意,但就是这样:

app.directive('wholeNumber', function() {
  return function(scope, elem, attrs) {
    elem.on("blur", function() {
      var num;
      num = parseInt(elem.val(), 10);
      num = Math.abs(num);
      scope.$apply(elem.val(num));
    });
  };
});

指令本身执行正确的DOM操作,但模型不会使用新值进行更新。

因此,这个问题有两个方面:

  1. 小提琴适用于在模型上设置正确的值,但模型文本不会更新。但是,在另一种方法中,我将模型itm的数量设置为1,它会更改模型和可见值。您会注意到它确实正确地更改了模型(注意绑定,足球数量= 1,例如当值设置为1.56时)。

  2. 为什么指令不会将更改传播到模型?

  3. 非常感谢, -Brian

2 个答案:

答案 0 :(得分:3)

<强>更新: 使用指令工作小提琴:http://jsfiddle.net/mrajcok/U7Je2/

突出点:

<input type="number" min="0" max="{{maxValue}}" data-ng-model="itm.qty" whole-number>

link: function(scope, elem, attrs) {
        elem.on("blur", function() {
            var num = Math.abs(parseInt(elem.val(), 10));
            num = num > scope.maxValue ? 0 : num;
            scope.itm.qty = num
            scope.$apply();

            // or, the above two lines can be rewritten as
            scope.$apply(scope.itm.qty = num);

        // or, the blur function can be rewritten as
        elem.on("blur", function() {
            scope.$apply(function() {
                var num = Math.abs(parseInt(elem.val(), 10));
                num = num > scope.maxValue ? 0 : num;
                scope.itm.qty = num;
            });
        });

原创“回答”:

关于你的第一个小提琴,最近在SO上出现了类似的问题,请参阅AngularJS - reset of $scope.value doesn't change value in template (random behavior)

如果我们将该帖子的$ timeout解决方案应用于您的问题,请将setQty()逻辑包装在$ timeout函数中,它将起作用。见this fiddle。我说“有点”因为可以输入像“2-2-3-4”这样的“数字”,“abc”也可以。当你改变焦点时,那些虚假的价值确实很明显。似乎Angular没有为这些伪造的条目调用setQty()......我不知道为什么。

答案 1 :(得分:0)

标记,

您的解决方案的问题是指令需要知道绑定变量的名称。一个更有用的解决方案是匿名更新它(并调用任何相关的事件),以便该指令可用于绑定到任何控制器的任何部分html:

// update the bound scope variable and if exists call the change function
var evalStr = attrs.ngModel + '=' + num.toString();
if (typeof attrs.ngChange != 'undefined')
{
  evalStr += ';'+attrs.ngChange;
}
scope.$apply(evalStr);

请注意,评估'evalStr'作为范围参数的优势。$ apply意味着AngularJS会向控制台报告任何异常,并且应用程序可以继续。