Angularjs 角度远程窗体未显示错误

Angularjs 角度远程窗体未显示错误,angularjs,angularjs-directive,angularjs-ng-resource,Angularjs,Angularjs Directive,Angularjs Ng Resource,我创建了一个显示从服务器收到的输入验证错误的角度表单。除了一个小问题外,我的解决方案运行良好。 如果我提交的表单没有值,则在页面加载后,我将从服务器(即422)收到正确的响应,但不会显示验证错误。如果我开始在输入中输入一个值,验证错误就会闪烁并消失 我几乎可以肯定这与我的指令有关,但我不确定如何修复它。这是我当前的指令代码: var appServices = angular.module('webFrontendApp.directives', []); appServices.direct

我创建了一个显示从服务器收到的输入验证错误的角度表单。除了一个小问题外,我的解决方案运行良好。 如果我提交的表单没有值,则在页面加载后,我将从服务器(即422)收到正确的响应,但不会显示验证错误。如果我开始在输入中输入一个值,验证错误就会闪烁并消失

我几乎可以肯定这与我的指令有关,但我不确定如何修复它。这是我当前的指令代码:

var appServices = angular.module('webFrontendApp.directives', []);

appServices.directive('serverError', function(){
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope,element,attrs,ctrl){
      element.on('change keyup', function(){
        scope.$apply(function(){
          ctrl.$setValidity('server', true);
        });
      });
    }
  };
});
我认为问题在于元素。在代码的('change keyup'…部分。这就是为什么我开始键入时错误消息会闪烁。此外,当我将此更改为'change'而不是'change keyup'时,错误消息在我开始键入时会永久显示

是否有人知道即使我在第一次提交之前没有在输入中键入任何值,我如何显示错误消息

根据评论更新

这是我的表格:

<form ng-submit="create(memberData)" name="form" novalidate>
  <div class = "row form-group" ng-class = "{ 'has-error' : form.email.$dirty && form.email.$invalid }">
     <input type="text" ng-model="memberData.email" placeholder="janedoe@mail.com"  name="email" class="col-xs-12 form-control" server-error>

     <span class="errors" ng-show="form.email.$dirty && form.email.$invalid">
       <span class="glyphicon glyphicon-remove form-control-feedback"></span>
       <span ng-show="form.email.$error.server">{{errors.email}}</span>
     </span>
  </div>
  <div class="row">
    <button type="submit" class="btn btn-danger col-xs-12">Join Private Beta</button>
  </div>
</form>

由于表单本身没有$setValidity方法,因为没有ng模型,并且假设服务器错误不涉及单个字段(在本例中,首选$setValidity方法),我认为最简单的解决方案可能是:

创建一个带有一些随机验证的表单(这个表单至少需要用户名)和一个可以显示自定义服务器错误的div

<div ng-controller="AppCtrl">

    <form novalidate name="createForm">

        <div class="inputWrap">

            <input ng-model="name" name="name" type="text" required placeholder="John Doe">

            <span ng-if="createForm.name.$dirty && createForm.name.$invalid">
                Some kind of error!
            </span>

        </div>

        <div ng-if="serverError">
            {{ serverError.message }}
        </div>

        <input
            value="Join Private Beta"
            ng-disabled="createForm.$invalid || serverError" 
            ng-click="create()"
            type="button">

    </form>

</div> 

我的意思是这是一个非常简单的片段,我只是想举个例子。没有什么复杂的,但你可以将它扩展到更复杂的地方。

似乎有一个非常简单的解决方法。因为我有过滤表单.email.$dirty,在我的视图中,如果用户没有先单击表单就单击submit,则不会显示错误


删除form.email.$dirty且仅具有form.email.$invalid之后,它就可以完美地工作。我认为在我的情况下,这就足够了,因为此验证依赖于服务器响应,并且在提交表单之前不会触发。在我的控制器中也会清除错误对象,以确保页面在提交时不会加载错误首先加载。

一些问题:您也可以编写表单吗?这是验证的全部逻辑?为什么$setValidity硬编码为true?我已经添加了流程的其他部分,作为对上面@MatteoGabriele问题的更新
<div ng-controller="AppCtrl">

    <form novalidate name="createForm">

        <div class="inputWrap">

            <input ng-model="name" name="name" type="text" required placeholder="John Doe">

            <span ng-if="createForm.name.$dirty && createForm.name.$invalid">
                Some kind of error!
            </span>

        </div>

        <div ng-if="serverError">
            {{ serverError.message }}
        </div>

        <input
            value="Join Private Beta"
            ng-disabled="createForm.$invalid || serverError" 
            ng-click="create()"
            type="button">

    </form>

</div> 
var AppCtrl = function($scope, YourService){

    // Properties

    // Shared Properties

    // Methods
    function initCtrl(){}

    // Shared Methods
    $scope.create = function(){

        YourService.makeCall().then(function(response){

            // Success!

            // Reset the custom error
            $scope.serverError = null;

        }, function(error){

            // Do your http call and then if there's an error
            // create the serverError object with a message
            $scope.serverError = {
                message : 'Some error message'
            };

        })

    };

    // Events

    // Init controller
    initCtrl();

};

AppCtrl.$inject = [
    '$scope',
    'YourService'
];

app.controller('AppCtrl', AppCtrl);