javascript – ngPattern绑定无法正常工作

前端之家收集整理的这篇文章主要介绍了javascript – ngPattern绑定无法正常工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想根据select的选择使用ngPattern验证输入.它在第一次选择后起作用,但任何后续选择都无法正确绑定.

这是一个jsFiddle供参考:
http://jsfiddle.net/PLRf5/17/

  1. <html>
  2. <head>
  3. <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.js"></script>
  4. <link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
  5. <style>
  6. .field-validation-error {
  7. color: red;
  8. }
  9. </style>
  10. </head>
  11. <body>
  12. <div class="container form-group" ng-app="mod1" ng-controller="ctrl1">
  13. <p>
  14. ng-pattern binding is not updating:
  15. Enter in 'asdf' then click Cuba. ngPattern should update and you should not see "Bad Format".
  16. </p>
  17.  
  18. <div ng-form="genericAddressEntry">
  19. <div class="form-group" data-ng-class="{ 'has-error': genericAddressEntry.country.$invalid }">
  20. <label for="country">Country</label>
  21. <select name="country" class="form-control"
  22. data-ng-model="selectedCountry"
  23. data-ng-options="country as country.name for country in countries"
  24. data-ng-required="true"
  25. >
  26. </select>
  27. </div>
  28.  
  29. <div class="clearFix" ng-bind="selectedCountry | countryToPostalCodeRegex"></div>
  30.  
  31. <div class="form-group " data-ng-class="{ 'has-error': genericAddressEntry.postalCode.$invalid }">
  32. <label for="postalCode">Zip Code</label>
  33.  
  34. <input name="postalCode" type="text" class="form-control" data-ng-model="editAddress.postalCode" data-ng-required="selectedCountry.requiresPostal"
  35. ng-pattern="selectedCountry | countryToPostalCodeRegex" maxlength="12" />
  36. <span class="field-validation-error" data-ng-show="genericAddressEntry.postalCode.$error.pattern">Bad Format</span>
  37. <span class="field-validation-error" data-ng-show="genericAddressEntry.postalCode.$error.required">required</span>
  38. </div>
  39.  
  40. </div>
  41. </div>
  42.  
  43. <script>
  44.  
  45.  
  46. //module:
  47. angular.module('mod1',[])
  48. .controller('ctrl1',['$scope',function ($scope) {
  49. // $scope.editAddress = { postalCode: "12345" };
  50. $scope.countries = [
  51. { name: 'United States',requiresPostal: true,postalRegEx: '^[0-9]{5}([-]?[0-9]{4})?$' },//{ name: 'Canada',postalRegEx: '^[a-yA-Y]\d[a-zA-Z]( )?\d[a-zA-Z]\d$' },{ name: 'Cuba',requiresPostal: false,postalRegEx: undefined }];
  52. $scope.selectedCountry = $scope.countries[0];
  53. }])
  54. .filter('countryToPostalCodeRegex',[function () {
  55. var allowAllRegex = new RegExp("^.*");
  56. var escapeRegex = function (str) {
  57. return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");
  58. }
  59.  
  60. return function (country) {
  61.  
  62. if (!country) {
  63. return allowAllRegex;
  64. }
  65. if (!country.requiresPostal) {
  66. return allowAllRegex;
  67. }
  68.  
  69. if (!country.postalRegExObj) {
  70. country.postalRegExObj = new RegExp(escapeRegex(country.postalRegEx),"i");
  71. }
  72. return country.postalRegExObj;
  73. };
  74. }]);
  75. </script>
  76.  
  77. </body>
  78. </html>

解决方法

目前,Angular不会监视仅监视绑定值的更改的属性.还有一些Angular问题在 NgMinlength And NgMaxlength – Set length value dynamically not workinginput does not watch ngPattern value for changes进一步讨论.来自caitp的两个主要评论是:

The general pattern of Angular isn’t to respond to actual changes to
an attribute value,but rather to respond to changes to a bound value.

The thing with this is that currently the pattern doesn’t come from a
parsed expression / scope variable,it’s just a string literal turned
into a regexp,so watching for changes to that means essentially
watching the DOM attribute value for change. I think I mentioned that
on a different issue regarding this a few weeks ago. Watching changes
to the actual DOM attribute is fairly different from what angular is
typically doing.

从这些问题中获取提示,并查看Angular implements ngPattern如何处理这一问题的方法添加一个指令,该指令监视ngPattern属性的Angular eval()以进行更改.如果它看到更改,那么它可以评估ngPattern正则表达式和setValidity.

这使我们可以动态监控属性值.这是指令:

  1. .directive('updatePattern',function() {
  2. return {
  3. require: "^ngModel",link: function(scope,element,attrs,ctrl) {
  4. scope.$watch(function() {
  5. // Evaluate the ngPattern attribute against the current scope
  6. return scope.$eval(attrs.ngPattern);
  7. },function(newval,oldval) {
  8. //Get the value from `ngModel`
  9. value = ctrl.$viewValue;
  10.  
  11. // And set validity on the model to true if the element
  12. // is empty or passes the regex test
  13. if (ctrl.$isEmpty(value) || newval.test(value)) {
  14. ctrl.$setValidity('pattern',true);
  15. return value;
  16. } else {
  17. ctrl.$setValidity('pattern',false);
  18. return undefined;
  19. }
  20. });
  21. }
  22. }
  23. });

我们将新的update-pattern指令添加到html中:

  1. <input name="postalCode" type="text" class="form-control" data-ng-model="editAddress.postalCode" data-ng-required="selectedCountry.requiresPostal"
  2. ng-pattern="selectedCountry | countryToPostalCodeRegex" maxlength="12" update-pattern />

working fiddle

猜你在找的JavaScript相关文章