当输入与模式不匹配时,$ watch不会在输入更改时调用

时间:2014-06-16 16:09:44

标签: asp.net-mvc angularjs angularjs-directive data-annotations

我使用ngVal使用基于ASP.NET MVC数据注释的AngularJS指令来装饰我的输入。

我的模型有以下注释:

[Display(Name="Test Number")]
[Required]
[RegularExpression(@"^[\d]{6}$", ErrorMessage = "The value must be six numbers.")]
public string TestNumber { get; set; }
然后使用

ngVal显示与输入字段关联的错误消息。

我可以确定(使用$ watch函数中的调试断点)是除非模式匹配,否则不会调用在修改范围中的值时应调用的函数。以下是ngVal指令如何设置范围。$ watch:

var ngval = angular.module('ngval', []);

ngval.directive('ngval', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, iElm, iAttrs, ngModel) {
            var messages = angular.fromJson(iAttrs.ngval);
            var getErrors = function() {
                var errors = [];
                for (var prop in messages) {
                    if (ngModel.$error[prop])
                        errors.push({ validator: prop, message: messages[prop] });
                }
                return errors;
            };
            scope.$watch(function() {
                return ngModel.$modelValue;
            }, function () {
                ngModel.ngval = {
                    hasError: ngModel.$dirty && ngModel.$invalid,
                    errors: getErrors()
                };
            });
        }
    };
}]);

结果是,最初我看到该字段是必需的,但输入无效的字符并不会将错误更改为为模式指定的错误 - 它仍然说该字段是必需的。这是因为没有调用给$ watch的函数。如果我输入6个数字,则该字段有效,并在此之后修改该值,显示模式不匹配消息。唯一的例外是如果我选择输入框的内容并按一下键(del / backspace)将其擦除。

这是正常行为吗?如果值与模式不匹配,则scope.$watch不会被调用?

编辑:我在输入上添加了ng-change指令,它的行为相同 - 如果输入与模式不匹配,则不会调用它。在这个问题上可以看到行为的证明:http://plnkr.co/edit/krmQVk0giwCYGxdY5YNS?p=preview

1 个答案:

答案 0 :(得分:0)

问题是手表是针对模型设置的,并且没有为与ngPattern不匹配的输入更改设置模型上属性的值。模型上的属性仅在与模式匹配时才更改为输入值;否则该属性被清空(空,未定义或空白 - 我不确定。

我所采用的解决方法是观察DOM元素的$ error属性,这些属性由AngularJS更新。我添加了一个formItem属性,允许将form和input元素的名称传递给HTML Helper方法,以便它可以将它添加到标记中。手表现在设置如下:

for (prop in messages) {
    scope.$watch(iAttrs.formitem + ".$error."+ prop,
        function() {
            ngModel.ngval = {
                hasError: ngModel.$dirty && ngModel.$invalid,
                errors: getErrors()
            };
        });
}

我希望能帮助那些有同样问题的人。