2016-07-23 19 views
6

我目前有一個角度指令驗證密碼並確認密碼字段爲匹配。它工作到一定程度,它在密碼不匹配時會引發錯誤。但是,它不會拋出錯誤,直到您在兩個字段中輸入數據。我該如何做到這一點,因爲一旦你在一個領域或另一個領域輸入數據,就會拋出不匹配密碼的錯誤。驗證密碼和確認密碼字段每當一個或其他字段模型更改(每個按鍵)與角度指令

這裏是指令(它被添加到需要符合這兩個領域):

.directive('passwordVerify', function() { 
    return { 
     restrict: 'A', // only activate on element attribute 
     require: '?ngModel', // get a hold of NgModelController 
     link: function(scope, elem, attrs, ngModel) { 
     //if (!ngModel) return; // do nothing if no ng-model 

     // watch own value and re-validate on change 
     scope.$watch(attrs.ngModel, function() { 
      validate(); 
     }); 

     // observe the other value and re-validate on change 
     attrs.$observe('passwordVerify', function(val) { 
      validate(); 
     }); 

     var validate = function() { 
      // values 
      var val1 = ngModel.$viewValue; 
      var val2 = attrs.passwordVerify; 

      // set validity 
      ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2); 
     }; 
     } 
    }; 
}); 

這裏是我的表格的指令:

<div class="small-5 columns"> 
      <div class="small-12 columns"> 
       <label>Password 
        <input ng-class="{ notvalid: submitted && add_user_form.user_password.$invalid }" class="instructor-input" id="user_password" type="password" name='user_password' placeholder="password" value='' required ng-model="user.user_password" password-verify="[[user.confirm_password]]"> 
       </label> 
       <p class="help-text"><span class=" ">Required</span></p> 
       <div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched || add_user_form.user_password.$dirty"> 
         <span class="red"><div ng-messages-include="/app/views/messages.html" ></div></span> 
        </div> 
      </div> 
      <div class="small-12 columns"> 
       <label>Confirm Password 
        <input ng-class="{ notvalid: submitted && add_user_form.confirm_password.$invalid }" class="instructor-input" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" name="user_confirm_passsword" required password-verify="[[user.user_password]]"> 
       </label> 
       <p class="help-text"><span class=" ">Enter matching password</span></p> 
       <div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$dirty || add_user_form.confirm_password.$touched "> 
         <span class="red"><div ng-messages-include="/app/views/messages.html" ></div></span> 
        </div> 
      </div> 
     </div> 
+0

你需要這樣調用密碼驗證=「[[user.confirm_password]]」,只是好奇,因爲我之前沒有在屬性調用中看到[[]]? – vodich

+0

是的,如果你不這樣做,它會假髮。我從別人那裏得到了這個指令,它有點搖搖欲墜。我認爲它正在驗證屬性中的數據而不是模型,這就是爲什麼它在[[]]中的原因,順便說一句,我是用{{}}替代的,因爲我使用的是句柄模板。因此,他編碼的方式是直接將模型中的數據輸入到屬性中,而不是直接比較模型中的數據。有關我如何改變這種情況的任何想法?我是新來的角,通常使用PHP做所有的MVC服務器端。 – OGZCoder

+0

嗯,你不能通過指令中的第二個輸入字段模型,並與更改時的當前輸入字段模型進行比較?如果您將代碼放在js-bin或jsFiddle上,我可能會幫助 – vodich

回答

8

只需更改最後一次檢查:

ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2); 

到:

ngModel.$setValidity('passwordVerify', val1 === val2); 

這裏有一個工作版本:

(function() { 
 
    "use strict"; 
 
    angular 
 
    .module('app', ['ngMessages']) 
 
    .controller('mainCtrl', mainCtrl) 
 
    .directive('passwordVerify', passwordVerify); 
 

 
    function mainCtrl($scope) { 
 
    // Some code 
 
    } 
 

 
    function passwordVerify() { 
 
    return { 
 
     restrict: 'A', // only activate on element attribute 
 
     require: '?ngModel', // get a hold of NgModelController 
 
     link: function(scope, elem, attrs, ngModel) { 
 
     if (!ngModel) return; // do nothing if no ng-model 
 

 
     // watch own value and re-validate on change 
 
     scope.$watch(attrs.ngModel, function() { 
 
      validate(); 
 
     }); 
 

 
     // observe the other value and re-validate on change 
 
     attrs.$observe('passwordVerify', function(val) { 
 
      validate(); 
 
     }); 
 

 
     var validate = function() { 
 
      // values 
 
      var val1 = ngModel.$viewValue; 
 
      var val2 = attrs.passwordVerify; 
 

 
      // set validity 
 
      ngModel.$setValidity('passwordVerify', val1 === val2); 
 
     }; 
 
     } 
 
    } 
 
    } 
 
})();
<html ng-app="app"> 
 

 
<head> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script> 
 
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" /> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script> 
 
</head> 
 

 
<body ng-controller="mainCtrl"> 
 
    <form name="add_user_form"> 
 
    <div class="col-md-12"> 
 
     <div class="form-group" ng-class="{ 'has-error' : add_user_form.user_password.$dirty && add_user_form.user_password.$invalid }"> 
 
     <p class="help-text">Enter password</p> 
 
     <input type="password" class="form-control" id="user_password" name="user_password" placeholder="password" required ng-model="user.user_password" password-verify="{{user.confirm_password}}"> 
 
     <div class="help-block" ng-messages="add_user_form.user_password.$error" ng-if="add_user_form.user_password.$dirty"> 
 
      <p ng-message="required">This field is required</p> 
 
      <p ng-message="minlength">This field is too short</p> 
 
      <p ng-message="maxlength">This field is too long</p> 
 
      <p ng-message="required">This field is required</p> 
 
      <p ng-message="passwordVerify">No match!</p> 
 
     </div> 
 
     </div> 
 
     <div class="form-group" ng-class="{ 'has-error' : add_user_form.confirm_password.$dirty && add_user_form.confirm_password.$invalid }"> 
 
     <p class="help-text">Enter matching password</p> 
 
     <input class="form-control" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" required password-verify="{{user.user_password}}"> 
 
     <div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-if="add_user_form.confirm_password.$dirty"> 
 
      <p ng-message="required">This field is required</p> 
 
      <p ng-message="minlength">This field is too short</p> 
 
      <p ng-message="maxlength">This field is too long</p> 
 
      <p ng-message="required">This field is required</p> 
 
      <p ng-message="passwordVerify">No match!</p> 
 
     </div> 
 
     </div> 
 
    </div> 
 
    </form> 
 
</body> 
 

 
</html>

我希望它能幫助。

+0

它很接近,但它仍然沒有在第一次擊鍵時拋出不匹配錯誤。在領域失去焦點後它拋出了錯誤。也許我的問題不清楚。我的錯。 @ developer033你對我整個項目的幫助很大。就像上次我最終想出了一種做我想做的事情的方式,但是以一種非常醜陋和「黑客」的方式。而且,我真的很不好,我在這裏使用了代碼,這裏我的添加用戶表單中的字段是在我的更新用戶表單中,除非其中一個字段爲空,否則不需要它們。 – OGZCoder

+0

這就是我想出的... [我的解決方案](http://plnkr.co/edit/2QTY770qW0FtYiZ21WtP?p=preview) – OGZCoder

+0

@OGJoshZero,沒問題的人,我在這裏幫助別人。不幸的是,你沒有解釋你想要同時顯示消息......順便說一句,你可以使用'$ dirty'而不是'$ touched',然後在用戶輸入時它會保持驗證狀態,所以你不需要需要做任何類型的破解..我改變了我的答案,檢查它。 – developer033

1

下面是一個簡單的工作方案。我們可以簡單地使用$validators在角1.3.0推出來達到相同:

var app = angular.module("sa", []); 
 

 
app.controller("FooController", function($scope) { 
 

 
}); 
 

 
app.directive('passwordVerify', function() { 
 
    return { 
 
    restrict: 'A', 
 
    require: '?ngModel', 
 
    link: function(scope, elem, attrs, ngModel) { 
 
     ngModel.$validators.myPwdInvalid = function(modelValue, viewValue) { 
 
     return viewValue === scope.$eval(attrs.passwordVerify); 
 
     }; 
 
    } 
 
    }; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> 
 

 
<form name="add_user_form" ng-app="sa" ng-controller="FooController"> 
 
    <div class="small-12 columns"> 
 
     <label>Password 
 
      <input ng-class="{ notvalid: add_user_form.user_password.$invalid }" 
 
        type="password" name='user_password' placeholder="password" required 
 
        ng-model="user.user_password" password-verify="user.confirm_password"> 
 
     </label> 
 

 
     <div class="help-block" ng-messages="add_user_form.user_password.$error" 
 
      ng-show="add_user_form.user_password.$error.$dirty || add_user_form.user_password.$touched"> 
 
      <div ng-messages="myPwdInvalid">Password do not match</div> 
 
     </div> 
 
    </div> 
 

 
    <div class="small-12 columns"> 
 
     <label>Confirm Password 
 
      <input ng-class="{ notvalid: add_user_form.confirm_password.$invalid }" 
 
        ng-model="user.confirm_password" 
 
        name="confirm_password" type="password" placeholder="confirm password" required 
 
        password-verify="user.user_password"> 
 
     </label> 
 

 
     <div class="help-block" ng-messages="add_user_form.confirm_password.$error" 
 
      ng-show="add_user_form.confirm_password.$error.$dirty || add_user_form.confirm_password.$touched"> 
 
      <div ng-messages="myPwdInvalid">Password do not match</div> 
 
     </div> 
 
    </div> 
 
</form>

0

這是爲我工作(醜陋的hackish):

HTML:

<h1>Password Verification</h1> 
<form name="pw" ng-controller="pw"> 
<p> 
    <label for="password">New Password 
    <input type="password" name="user_password" ng-model="user_password" ng-required="confirm_password && !user-password" password-verify="confirm_pasword"> 
    <p ng-show="pw.user_password.$error.passwordVerify">Passwords do not match</p> 
    <p ng-show="pw.user_password.$error.required">This field is required</p> 
    </label> 
</p> 
<p> 
    <label for="password">Confirm Password 
    <input type="password" name="confirm_password" ng-model="confirm_password" ng-required="user_password && !confirm_password" password-verify="user_password"> 
    <p ng-show="pw.confirm_password.$error.passwordVerify">Passwords do not match</p> 
    <p ng-show="pw.confirm_password.$error.required">This field is required</p> 
    </label> 
</p> 
</form> 

然後腳本:

angular.module('app', []) 
.controller('pw', ['$scope', function($scope){ 
    $scope.user_password = ""; 
    $scope.confirm_password = ""; 

}]) 
.directive('passwordVerify', function() { 
    return { 
     restrict: 'A', 
     require: '?ngModel', 
     link: function(scope, elem, attrs, ngModel) { 
      scope.$watch(attrs.ngModel, function() { 
       if (scope.confirm_password === scope.user_password) { 
        scope.pw.confirm_password.$setValidity('passwordVerify', true); 
        scope.pw.user_password.$setValidity('passwordVerify', true); 
       } else if (scope.confirm_password !== scope.user_password) { 
        scope.pw.confirm_password.$setValidity('passwordVerify', false); 
        scope.pw.user_password.$setValidity('passwordVerify', false); 
       } 
      }); 
     } 
    }; 
}); 
+0

既然你想同時驗證兩個輸入,你不需要全部。您可以將其更改爲:'var matches = scope.confirm_password === scope.user_password; scope.pw.confirm_password。$ setValidity('passwordVerify',matches); scope.pw.user_password。$ setValidity('passwordVerify',matches);'並取出大量不必要的代碼。 – developer033

+0

在這個解決方案中的壞處是,你現在依賴於你的視圖,如果你改變你的表單名稱或兩個領域之一,它將不再工作。 – developer033