AngularJS密码验证问题排查:自定义指令失效
Looks like you're stuck on getting your custom password validation directive working—let's break down the issues and fix this step by step.
First, I notice a possible typo in your directive name: you've named it myPassord (missing a 'w'). In AngularJS, directive names are camelCased in JS, and map to kebab-case in your HTML (like my-password). If your HTML uses my-password but your directive is misspelled, that could prevent it from triggering at all. Let's start by correcting that.
Next, your validation logic is incomplete, and you're not properly updating the model's validity state. Here's the revised, working version of your directive, plus explanations of what was missing:
app.directive('myPassword', function() { return { require: 'ngModel', link: function(scope, element, attr, ngModelCtrl) { // Add a validator to the ngModel controller ngModelCtrl.$validators.specialChar = function(modelValue, viewValue) { var value = modelValue || viewValue; // Check if value contains at least one of the required special characters var hasSpecialChar = value.indexOf("$") > -1 || value.indexOf("%") > -1 || value.indexOf("^") > -1; // Set the validity state: true if valid, false otherwise return hasSpecialChar; }; } }; });
Key Fixes & Improvements:
- Corrected directive name: Changed
myPassordtomyPasswordto match standard naming conventions and avoid mismatches with your HTML attribute. - Used
$validators(AngularJS 1.3+): This is the recommended way to add custom validators—it's cleaner than manually handling$parsersor$formatters. The validator function automatically runs whenever the model or view value changes. - Proper validity check: Explicitly checks for each special character and returns a boolean to indicate if the value is valid. AngularJS automatically sets the
$error.specialCharflag based on this return value. - Handled both model and view values: Used
modelValue || viewValueto cover cases where either the model or view might be updated (e.g., when the user types vs. when the model is set programmatically).
How to Use This in Your HTML:
Make sure your input uses the kebab-case version of the directive, and you can display validation errors using the form's $error object:
<form name="myForm"> <input type="password" name="password" ng-model="user.password" my-password ng-minlength="8" required> <!-- Show error if special character is missing --> <div ng-show="myForm.password.$error.specialChar"> Password must contain at least one of $, %, or ^ </div> <!-- Show error if length is too short --> <div ng-show="myForm.password.$error.minlength"> Password must be at least 8 characters long </div> </form>
Why Your Original Code Might Have Failed:
- Typo in directive name: If your HTML used
my-passwordbut your directive was namedmyPassord, AngularJS wouldn't recognize the directive binding. - Missing validity state update: In older approaches (pre-1.3), you needed to manually call
ngModelCtrl.$setValidity('specialChar', hasSpecialChar)to update the validity state. The$validatorsAPI handles this automatically now. - Incomplete validation logic: Your original code cut off at
value.indexOf("^") &...—we've completed the logic to check for all required special characters.
Let me know if you run into any other issues with this!
内容的提问来源于stack exchange,提问作者Binay Dhawa

