我正在使用三个输入在Angular中创建一个注册表单:emailpasswordpasswordConfirm。我的 Controller 如下所示:

app.controller('SignupController', function ($scope, User) {
    $scope.user = {};

    $scope.signup = function() {
        User.save($scope.user, function(success) {
            // TODO
        }, function(error) {
            if (error.status === 422) {
                error.data.errors.forEach(function(item) {
                    $scope.signupForm[item.field].$setValidity(item.error, false);
                });
            }
        });
    };
});

这是在用户提交表单进行注册时向我的API发送请求。如果返回422响应(这意味着验证错误),我将循环遍历它们,并根据API返回的内容将相应的输入设置为无效。

让我们以一个已经注册的电子邮件地址为例。我在 View 中显示验证错误,如下所示:
<small class="error" ng-show="signupForm.email.$error.exists">Email address taken, please use another</small>

所有这些都可以正常运行,但是我的用户现在陷入困境,因为当他们尝试将电子邮件地址更改为另一个电子邮件地址时,email字段的有效性并未更改,以允许他们重新提交表单(我基于表单禁用了提交按钮有效性)。

基本上,我需要在用户更改输入模型后将验证属性(在本例中为exists)重置为true。对我来说最好的方法是什么?

编辑:发布后,我被一个小脑波击中,我将此添加到了我的 Controller 中:
$scope.$watch('user.email', function() {
    // Reset exists validation property back to true
    $scope.signupForm.email.$setValidity('exists', true);
});

这似乎有效。当用户将输入设置为无效后更改模型值时,这会将其重新设置为有效。但这并没有使我成为执行此操作的最佳方法。有人知道吗?

最佳答案

我也在这个问题上苦苦挣扎。阅读您的文章后,我想出了一个可能的解决方案-创建一个指令,该指令监视模型的更改并在更改时重置有效性状态(基本上是您的建议,但放入了通用指令)

angular.module('app').directive('resetValidityOnChange', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, iElem, iAttrs, ngModelCtrl) {
            ngModelCtrl.$viewChangeListeners.push(function () {
                ngModelCtrl.$setValidity(iAttrs['resetValidityOnChange'], true);
            });
        }
    }
}

您将不得不将此指令添加到您想重置的输入中,例如:
<input type="text" ng-model="vm.email" reset-validity-on-change="exists" />

10-05 20:49
查看更多