0

我有一个 Angular JS 应用程序,其中有一个必填的电话号码字段,以及一个国家/地区选择字段。国家选择默认为美国。When the selected country is United States or Canada, I want to validate the phone number field with a domestic phone number pattern, but when any other country is selected, I don't want to validate the pattern for the phone number.

为了实现这个期望的功能,我使用了一个类似的解决方案肮脏的方式)。我不是检查requireTel布尔值,而是检查是否countryCodeUSACAN确定是否使用我的电话号码模式进行验证。

此解决方案有效,但前提是您更改国家/地区后更改电话号码。例如,如果您选择了美国,并输入一个长的国际电话号码,如+441234567890,它使用国内电话号码验证并显示无效模式。但是当我将国家更改为巴哈马时,它应该不再使用国内电话号码验证,并且无效模式消息应该消失。但是,在我更改电话号码之前,仍然会显示无效模式消息。一旦我更改了电话号码,消息就会消失。

发生这种情况的原因是,当更改国家/地区选择时,不会再次对电话号码字段执行 ng-pattern 验证。有没有办法在国家改变时强制重新评估 ng-pattern 验证?

请参阅下面的片段以重现该问题。

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

app.controller('exampleCtrl', function($scope) {
  $scope.countries = [{
    countryName: 'United States',
    countryCode: 'USA'
  }, {
    countryName: 'Canada',
    countryCode: 'CAN'
  }, {
    countryName: 'Bahamas',
    countryCode: 'BHS'
  }, {
    countryName: 'Chile',
    countryCode: 'CHL'
  }];

  $scope.selectedCountry = $scope.countries[0];

  $scope.phoneNumberPattern = (function() {
    var regexp = /^\(?(\d{3})\)?[ .\/-]?(\d{3})[ .-]?(\d{4})$/;
    return {
      test: function(value) {
        var countryCode = $scope.selectedCountry.countryCode;
        if (countryCode !== 'USA' && countryCode !== 'CAN') {
          return true;
        }
        return regexp.test(value);
      }
    }
  })();

});
.error {
  color: red;
  font-style: italic;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="example" ng-controller="exampleCtrl">
  <ng-form name="exampleForm">
    <label>Country:</label>
    <select ng-model="selectedCountry" ng-options="country as country.countryName for country in countries">
    </select>
    <label>Phone:</label>
    <input type="text" ng-model="phone" name="phone" ng-pattern="phoneNumberPattern" required>
    <small class="error" ng-show="exampleForm.phone.$error.pattern">Invalid pattern.</small>
    <small class="error" ng-show="exampleForm.phone.$error.required">Phone number is required.</small>
  </ng-form>
</div>

4

2 回答 2

1

这是另一个解决方案。使用返回模式的函数。

jsfiddle上的实时示例。

angular.module('ExampleApp', [])
  .controller('ExampleController', function($scope) {
    $scope.countries = [{
      countryName: 'United States',
      countryCode: 'USA'
    }, {
      countryName: 'Canada',
      countryCode: 'CAN'
    }, {
      countryName: 'Bahamas',
      countryCode: 'BHS'
    }, {
      countryName: 'Chile',
      countryCode: 'CHL'
    }];

    $scope.selectedCountry = $scope.countries[0];
    var regUSA = /^\(?(\d{3})\)?[ .\/-]?(\d{3})[ .-]?(\d{4})$/;
    var regAll = /.*/;
    $scope.phoneNumberPattern = function() {
      var countryCode = $scope.selectedCountry.countryCode;
      if (countryCode !== 'USA' && countryCode !== 'CAN')
        return regAll;
      else
        return regUSA;
    }
  });
.error {
  color: red;
  font-style: italic;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="ExampleApp">
  <div ng-controller="ExampleController">
    <ng-form name="exampleForm">
      <label>Country:</label>
      <select ng-model="selectedCountry" ng-options="country as country.countryName for country in countries">
      </select>
      <label>Phone:</label>
      <input type="text" ng-model="phone" name="phone" ng-pattern="phoneNumberPattern()" required>
      <small class="error" ng-show="exampleForm.phone.$error.pattern">Invalid pattern.</small>
      <small class="error" ng-show="exampleForm.phone.$error.required">Phone number is required.</small>
    </ng-form>
  </div>
</div>

注意: 在函数外部声明正则表达式变量很重要。如果您尝试通过以下方式更改方法:

if (countryCode !== 'USA' && countryCode !== 'CAN')
    return /.*/;
else
    return /^\(?(\d{3})\)?[ .\/-]?(\d{3})[ .-]?(\d{4})$/;

这将导致无限$digest错误

于 2016-02-23T04:42:56.630 回答
0

这是解决问题的一种方法。

我基本上所做的是将 a 添加ng-change="changed()"到下拉列表中。

<select ng-model="selectedCountry" ng-change="changed()" ng-options="country as country.countryName for country in countries">
    </select>

在JS中,我重置了输入文本框的值

 $scope.changed=function()
  {
    $scope.phone="";
  }

这会强制再次执行验证。

这是演示

让我知道此解决方案是否适合您。

于 2016-02-23T04:18:16.123 回答