【问题标题】:$watch not invoked on input change when input doesn't match the pattern当输入与模式不匹配时,不会在输入更改时调用 $watch
【发布时间】:2014-08-06 12:42:12
【问题描述】:

我正在使用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 指令,它的行为相同 - 如果输入与模式不匹配,则不会调用它。可以在此 plunker 中看到该行为的演示:http://plnkr.co/edit/krmQVk0giwCYGxdY5YNS?p=preview

【问题讨论】:

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


    【解决方案1】:

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

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

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

    我希望能帮助遇到同样问题的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多