Câu hỏi chỉ thị kiểm tra mật khẩu trong angularjs


Tôi đang viết một mật khẩu xác minh chỉ thị:

 Directives.directive("passwordVerify",function(){
    return {
        require:"ngModel",
        link: function(scope,element,attrs,ctrl){
            ctrl.$parsers.unshift(function(viewValue){
                var origin = scope.$eval(attrs["passwordVerify"]);
                if(origin!==viewValue){
                    ctrl.$setValidity("passwordVerify",false);
                    return undefined;
                }else{
                    ctrl.$setValidity("passwordVerify",true);
                    return viewValue;
                }
            });

        }
    };
});

html:

<input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
<input data-ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">

Cho 2 trường mật khẩu trong một biểu mẫu, nếu cả hai giá trị mật khẩu đều bằng nhau thì trường bị ảnh hưởng bởi chỉ thị là hợp lệ. Vấn đề là nó hoạt động theo một cách (tức là khi tôi nhập mật khẩu vào trường xác minh mật khẩu). Tuy nhiên, khi trường mật khẩu ban đầu được cập nhật, việc xác minh mật khẩu không hợp lệ.

Bất kỳ ý tưởng làm thế nào tôi có thể có một "hai cách ràng buộc xác minh?"


75
2017-12-23 15:34


gốc




Các câu trả lời:


Điều này sẽ giải quyết nó:

Lượt xem:

<div ng-controller='Ctrl'>
   <form name='form'>
      <input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
      <div ng-show="form.password.$error.required">
        Field required</div>
      <input ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">
      <div ng-show="form.confirm_password.$error.required">
        Field required!</div>
      <div ng-show="form.confirm_password.$error.passwordVerify">
        Fields are not equal!</div>
   </form
</div>

Chỉ thị

var app = angular.module('myApp', []);

app.directive("passwordVerify", function() {
   return {
      require: "ngModel",
      scope: {
        passwordVerify: '='
      },
      link: function(scope, element, attrs, ctrl) {
        scope.$watch(function() {
            var combined;

            if (scope.passwordVerify || ctrl.$viewValue) {
               combined = scope.passwordVerify + '_' + ctrl.$viewValue; 
            }                    
            return combined;
        }, function(value) {
            if (value) {
                ctrl.$parsers.unshift(function(viewValue) {
                    var origin = scope.passwordVerify;
                    if (origin !== viewValue) {
                        ctrl.$setValidity("passwordVerify", false);
                        return undefined;
                    } else {
                        ctrl.$setValidity("passwordVerify", true);
                        return viewValue;
                    }
                });
            }
        });
     }
   };
});

59
2017-12-23 16:15



Tôi đã sử dụng đoạn mã xác thực trong tài liệu, hãy để tôi thử mã của bạn. - mpm
Tôi đã thay đổi câu trả lời của mình. Điều này sẽ làm việc. Xem jsFiddle - asgoth
Điều này vẫn không cung cấp cho 2 cách ràng buộc, hoặc một cái gì đó đã thay đổi kể từ đó? - Hadesara
Tôi đồng ý với CWSpear. Giải pháp cần được sửa chữa bằng lỗi đã nhận xét ở trên - gyss
Có một rò rỉ bộ nhớ với giải pháp này. Mỗi sự kiện xem được kích hoạt bằng cách đẩy một trình phân tích cú pháp khác vào ctrl. Kiểm tra ctrl. $ Parsers.length ở cuối trình xử lý sự kiện đồng hồ sẽ hiển thị điều này. - mshiltonj


Tôi sử dụng chỉ thị sau bởi vì tôi muốn xác thực lại cả hai trường đầu vào bất kể giá trị 1 hoặc giá trị 2 đã được thay đổi hay chưa:

chỉ thị:

'use strict';

angular.module('myApp').directive('equals', 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('equals', function (val) {
        validate();
      });

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

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

sử dụng

<input type="password" ng-model="value1" equals="{{value2}}" required>
<input type="password" ng-model="value2" equals="{{value1}}" required>

114
2017-08-02 10:42



Tôi thấy điều này hoạt động khá tốt. Một điều khiến tôi mất cảnh giác là nếu bạn có một số trình xác nhận góc khác như: ng-minlengthtrên trường đầu tiên, thì mô hình đó không được đặt cho đến khi nó thực sự hợp lệ - Dominic Watson
Tôi bọc ngModel.$setValidity với if (val1 && val2) { .. } chỉ vì vậy biểu mẫu không hợp lệ khi cả hai giá trị đều trống. - jesal
Điều này có một số vấn đề nhỏ khi có nhiều quy tắc xác thực hơn khi chơi. Nếu xác thực khác không thành công, Angular không cập nhật mô hình và những thứ kỳ lạ xảy ra trong so sánh ... - user2173353
Nó hiệu quả tuyệt vời đối với tôi. Là một newbie nó sẽ giúp thêm chuỗi xác nhận này. [form name].[field name].$error.equals Sử dụng điều này để kiểm soát những trường nào nên hiển thị. Tôi đang sử dụng nó cho các nhãn lỗi. - metric152
Tôi nghĩ tốt hơn nên thay thế ngModel.$setValidity('equals', val1 === val2); với ngModel.$setValidity('equals', ! val1 || ! val2 || val1 === val2); - bullgare


Việc tạo một chỉ thị riêng cho điều này là không cần thiết. Đã có một xây dựng trong công cụ xác thực mật khẩu giao diện người dùng góc. Với điều này bạn có thể làm:

<input name="password" required ng-model="password">
<input name="confirm_password"
       ui-validate=" '$value==password' "
       ui-validate-watch=" 'password' ">

 Passwords match? {{!!form.confirm_password.$error.validator}}

85
2017-10-24 07:32



hiện đang yêu cầu jQuery - Dominic Watson
@DominicWatson Những gì bạn đang downvoting tôi cho? Câu hỏi này là về góc cạnh và tôi đề cập đến các tài liệu góc. Tìm hiểu nó nếu bạn không hiểu sự khác biệt giữa chúng. - bicycle
@DominicWatson Chỉ thị ở đây github.com/angular-ui/ui-utils/blob/master/modules/validate/… ngoại trừ từ jquery lite không có jquery freaking trong đó. Nếu bạn đang chống jquery như vậy bạn không nên sử dụng khung này anyway vì nó kết hợp jquery. - bicycle
Tôi đang gặp vấn đề tương tự như bài đăng gốc. Nếu có cái gì đó đã được xây dựng trong angular-ui nó không có ý nghĩa để sử dụng nó thay vì tái phát minh ra bánh xe? - PeterG
@ Peter Tôi không nghĩ Dominic Watson có một đầu mối những gì ông đã nói về - bicycle


Một tính năng khác nữa là để phù hợp với mô hình của một đầu vào cho giá trị đầu vào khác.

app.directive('nxEqual', function() {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, model) {
            if (!attrs.nxEqual) {
                console.error('nxEqual expects a model as an argument!');
                return;
            }
            scope.$watch(attrs.nxEqual, function (value) {
                model.$setValidity('nxEqual', value === model.$viewValue);
            });
            model.$parsers.push(function (value) {
                var isValid = value === scope.$eval(attrs.nxEqual);
                model.$setValidity('nxEqual', isValid);
                return isValid ? value : undefined;
            });
        }
    };
});

Vì vậy, nếu mô hình của hộp mật khẩu là login.password sau đó bạn đặt thuộc tính sau trên hộp xác minh: nx-equal="login.password"và kiểm tra formName.elemName.$error.nxEqual. Giống như vậy:

<form name="form">
    <input type="password" ng-model="login.password">
    <input type="password" ng-model="login.verify" nx-equal="login.password" name="verify">
    <span ng-show="form.verify.$error.nxEqual">Must be equal!</span>
</form>

Phiên bản mở rộng:

Đối với một dự án mới của tôi, tôi phải sửa đổi chỉ thị trên để nó chỉ hiển thị nxEqual lỗi khi và chỉ khi nào, đầu vào xác minh có giá trị. Nếu không nxEqual lỗi nên được tắt tiếng. Đây là phiên bản mở rộng:

app.directive('nxEqualEx', function() {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, model) {
            if (!attrs.nxEqualEx) {
                console.error('nxEqualEx expects a model as an argument!');
                return;
            }
            scope.$watch(attrs.nxEqualEx, function (value) {
                // Only compare values if the second ctrl has a value.
                if (model.$viewValue !== undefined && model.$viewValue !== '') {
                    model.$setValidity('nxEqualEx', value === model.$viewValue);
                }
            });
            model.$parsers.push(function (value) {
                // Mute the nxEqual error if the second ctrl is empty.
                if (value === undefined || value === '') {
                    model.$setValidity('nxEqualEx', true);
                    return value;
                }
                var isValid = value === scope.$eval(attrs.nxEqualEx);
                model.$setValidity('nxEqualEx', isValid);
                return isValid ? value : undefined;
            });
        }
    };
});

Và bạn sẽ sử dụng nó như vậy:

<form name="form">
    <input type="password" ng-model="login.password">
    <input type="password" ng-model="login.verify" nx-equal-ex="login.password" name="verify">
    <span ng-show="form.verify.$error.nxEqualEx">Must be equal!</span>
</form>

Thử nó: http://jsfiddle.net/gUSZS/


22
2018-02-24 15:31



Cái này là tốt nhất. Nó gọn gàng nhất. Nó hoạt động trên các giá trị mô hình và nó hoạt động theo cả hai cách. - CMCDragonkai
Tuy nhiên, có một điều là ống $ parser trả về giá trị hoặc không xác định. Bằng cách đó, các ống tiếp theo không chỉ kết thúc vì nó luôn luôn được trả về không xác định khi không có hàm trả về. Phạm vi cũng phải là sai. - CMCDragonkai
@ CMCDragonkai: Tốt bắt! Tôi đã cập nhật giá trị trả lại của hàm phân tích cú pháp. Về phạm vi, theo như tôi biết nó mặc định false, do đó, bằng cách không chỉ định rõ ràng phạm vi, nó bằng scope: false. - Fredric
Tôi nghĩ rằng nó thực sự mặc định là đúng là một phạm vi con. Nhưng tôi chưa kiểm tra gần đây. - CMCDragonkai
@GillBates Sử dụng một phạm vi bị cô lập và ràng buộc đối số bằng cách = sẽ không xem xét lại đầu vào đầu tiên sau khi nó được điền vào. Tôi đã thực hiện một cách nhanh chóng JSFiddle hiển thị vấn đề này. - Fredric


Tôi đã làm điều đó mà không có chỉ thị.

<input type="password" ng-model="user.password" name="uPassword" required placeholder='Password' ng-minlength="3" ng-maxlength="15" title="3 to 15 characters" />
    <span class="error" ng-show="form.uPassword.$dirty && form.uPassword.$error.minlength">Too short</span>
    <span ng-show="form.uPassword.$dirty && form.uPassword.$error.required">Password required.</span><br />

    <input type="password" ng-model="user.confirmpassword" name="ucPassword" required placeholder='Confirm Password' ng-minlength="3" ng-maxlength="15" title="3 to 15 characters" />
    <span class="error" ng-show="form.ucPassword.$dirty && form.ucPassword.$error.minlength">Too short</span>
    <span ng-show="form.ucPassword.$dirty && form.ucPassword.$error.required">Retype password.</span>
    <div ng-show="(form.uPassword.$dirty && form.ucPassword.$dirty) && (user.password != user.confirmpassword)">
        <span>Password mismatched</span>
    </div>

14
2018-05-14 05:59



Bạn nên sử dụng một chỉ thị như đã được chỉ ra, biểu mẫu vẫn ở trạng thái hợp lệ. Nếu không, bạn có thể cũng đã thực hiện một số người nghe jquery cho nó. - bicycle


https://github.com/wongatech/angular-confirm-field là một dự án tốt cho việc này.

Ví dụ ở đây http://wongatech.github.io/angular-confirm-field/

Mã bên dưới hiển thị 2 trường nhập với chức năng được triển khai

<input ng-confirm-field ng-model="emailconfirm" confirm-against="email" name="my-email-confirm"/>
<input ng-model="email" name="my-email" />

8
2017-08-07 09:18





Kể từ góc 1.3.0-beta12, đầu vào không hợp lệ không ghi vào ngModel, vì vậy bạn không thể xem VÀ THEN xác thực như bạn có thể thấy ở đây: http://plnkr.co/edit/W6AFHF308nyKVMQ9vomw?p=preview. Một đường xác nhận hợp lệ mới đã được giới thiệu và bạn có thể đính kèm vào điều này để đạt được điều tương tự.

Trên thực tế, trên lưu ý đó tôi đã tạo ra một thành phần bower cho các trình xác nhận hợp lệ bổ sung: https://github.com/intellix/angular-validators bao gồm điều này.

angular.module('validators').directive('equals', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function(scope, elem, attrs, ngModel)
        {
            if (!ngModel) return;

            attrs.$observe('equals', function() {
                ngModel.$validate();
            });

            ngModel.$validators.equals = function(value) {
                return value === attrs.equals;
            };
        }
    };
});

angular.module('validators').directive('notEquals', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function(scope, elem, attrs, ngModel)
        {
            if (!ngModel) return;

            attrs.$observe('notEquals', function() {
                ngModel.$validate();
            });

            ngModel.$validators.notEquals = function(value) {
                return value === attrs.notEquals;
            };
        }
    };
});

8
2017-07-30 08:19



giải pháp tốt nhất cho đến nay tôi đoán - Rachmaninoff


Tôi đã sử dụng chỉ thị này với thành công trước đây:

 .directive('sameAs', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {
        if (viewValue === scope[attrs.sameAs]) {
          ctrl.$setValidity('sameAs', true);
          return viewValue;
        } else {
          ctrl.$setValidity('sameAs', false);
          return undefined;
        }
      });
    }
  };
});

Sử dụng

     <input ... name="password" />
    <input type="password" placeholder="Confirm Password" 
name="password2" ng-model="password2" ng-minlength="9" same-as='password' required>

7
2017-08-01 18:50



Tôi thích giải pháp này là tốt nhất - không hạn chế nó để phù hợp với mật khẩu - Shaz
Nó không hoạt động hai chiều. - Adam