2015-09-06 11 views
0

我創建了一個角度窗體,顯示從服務器接收到的輸入驗證錯誤。除了一個小問題,我的解決方案很好。 如果我提交沒有值的表單,頁面加載後,我收到來自我的服務器(即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); 
     }); 
     }); 
    } 
    }; 
}); 

我認爲這個問題是與element.on(「改變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="[email protected]" 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> 

而且我的控制器:

$scope.memberData = {}; 
$scope.create = function() { 
    var error, success; 
    $scope.errors = {}; 
    success = function() { 
     $scope.memberData = {}; 
    };  
    error = function(result) { 
     angular.forEach(result.data.errors, function(errors, field) { 
      $scope.form[field].$setValidity('server', false); 
      $scope.errors[field] = errors.join(', '); 
     });  
    }; 



    BetaMember.save({ beta_member: { email: $scope.memberData.email || "" }}).$promise.then(success, error); 

}; 
+0

有些問題: 你也可以寫表格嗎? 這是驗證的所有邏輯? 爲什麼$ setValidity被硬編碼爲true? –

+0

我已經將流程的其他部分添加爲我上面的問題的更新@MatteoGabriele – Herm

回答

0

似乎有一個非常簡單的解決方法。因爲我的視圖中有過濾器form.email。$ dirty,所​​以如果用戶沒有先點擊表單,點擊提交就不會顯示錯誤。

刪除form.email。$ dirty並且只有form.email。$無效後,才能正常工作。我認爲這對我來說已經足夠了,因爲此驗證依賴於服務器響應,並且在提交表單之前不會觸發。錯誤對象也在我的控制器中清除,確保頁面在第一次加載時不會加載錯誤。

0

由於形式本身不具有$ 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> 

然後在你的控制器,你可以添加創建方法處理YourService(應返回一個承諾),如果反應是失敗的,你可以創建一個內部的自定義服務器錯誤消息的簡單對象如果需要,這也將是有用的禁用窗體按鈕。

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); 

我的意思是這裏的代碼非常簡單,我只是想舉一個例子。沒有什麼複雜的,但你可以擴展到更多。