(Angular2/4/5/6) 如何根据国家/地区验证国际 phone 号码的长度

(Angular2/4/5/6) How to validate length of international phone numbers according to country

是否有 library/service class 可用于单独验证国际手机号码?例如。新加坡手机号码必须有 8 位数字,中国 11 位数字等。目前我正在使用反应形式格式的 ng4-intl-phone 以允许用户输入他们的手机号码。

验证应该根据每个国家出现,而不是对国际 phone 号码的一般检查,比如号码是 3 到 14 位数字(这是我之前使用的)。

感谢您的帮助!

更新

我暂时用https://www.npmjs.com/package/ngx-international-phone-number代替。如果有需要的人可以参考,我还是会在下面留下答案!

我在我的 angular 6 项目中使用了 libphonenumber-js,它工作得很好。

这是我的自定义解决方案。它适用于我的解决方案。

请为您的项目安装 intl-tel-input

npm i intl-tel-input --save

然后创建一个IntlTelInputComponent组件如下。

国际电话input.component.ts

import {
  AfterViewInit, Component, ElementRef, EventEmitter, Input, Output, ViewChild, forwardRef, Renderer
} from '@angular/core';
import 'intl-tel-input';
import * as jQuery from 'jquery';
import { NG_VALUE_ACCESSOR, ControlValueAccessor, } from '@angular/forms';

export interface ITimeInputFieldChanged {
  value: string;
  extension: string;
  numberType: string,
  valid: boolean;
  validationError: any
}

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => IntlTelInputComponent),
  multi: true
};

const noop = () => {
};

@Component({
  selector: 'intl-tel-input',
  templateUrl: './intl-tel-input.component.html',
  styleUrls: ['./intl-tel-input.component.scss'],
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})

export class IntlTelInputComponent implements ControlValueAccessor {

  @Input() fullValue: string;
  @Output() fullValueChange = new EventEmitter<ITimeInputFieldChanged>();
  @Input() id: string;
  @Input() intlOptions = {
    initialCountry: 'no',
    formatOnDisplay: true,
    separateDialCode: true,
    onlyCountries: ['no', 'be']
  };
  @Input() value: string;
  @Output() valueChange = new EventEmitter<string>();
  @Output() valueBlur = new EventEmitter<string>();
  @Output() valueFocus = new EventEmitter();
  @ViewChild('intlInput') intlInput: ElementRef;

  private extension: string;

  private onTouchedCallback: () => void = noop;
  private onChangeCallback: (_: any) => void = noop;

  constructor(
    private _renderer: Renderer) { }

  onInputChange(value: string) {
    const intlInput = jQuery(this.intlInput.nativeElement)
    this.value = value;
    this.valueChange.emit(value);
    this.fullValue = intlInput.intlTelInput('getNumber');
    this.extension = intlInput.intlTelInput('getSelectedCountryData').dialCode;
    const validationErrorCode = intlInput.intlTelInput('getValidationError');
    let validationMessage = 'VALID';
    switch (validationErrorCode) {
      case 1:
        validationMessage = 'INVALID_COUNTRY_CODE'
        break;
      case 2:
        validationMessage = 'TOO_SHORT'
        break;
      case 3:
        validationMessage = 'TOO_LONG'
        break;
      case 4:
        validationMessage = 'NOT_A_NUMBER'
        break;
      case 5:
        break;
      default:
        validationMessage = 'VALID'
        break;
    }
    this.fullValueChange.emit({
      value: value,
      extension: this.extension,
      numberType: intlInput.intlTelInput('getNumberType'),
      valid: intlInput.intlTelInput('isValidNumber'),
      validationError: validationMessage
    });
    // this.writeValue(this.fullValue);
  }

  onBlur(value: string) {
    this.valueBlur.emit(value);
  }

  onFocus() {
    this.valueFocus.emit();
  }

  writeValue(value: any): void {

    if (value && (value !== this.value)) {
      this.fullValue = value;
      setTimeout(() => {
        const phoneInput = jQuery(`input#${this.id}`);
        phoneInput.intlTelInput('setNumber', this.fullValue);
      }, 100);
    }
  }
  registerOnChange(fn: any): void {
    this.onChangeCallback = fn;
  }

  registerOnTouched(fn: () => any): void { this.onTouchedCallback = fn; }

  setDisabledState?(isDisabled: boolean): void {
    throw new Error('Method not implemented.');
  }

}

国际电话input.component.html

<input #intlInput class="form-control"
[appIntlTelInput]="intlOptions"
[id]="id"
[ngModel]="value"
(ngModelChange)="onInputChange($event)"
(blur)="onBlur($event)"
(focus)="onFocus()"
>

国际电话input.component.scss

:host /deep/.intl-tel-input{
    display: block;
    .country-list{
        overflow-y: auto;
    }
}

国际电话input.directive.ts

import { Directive, ElementRef, Input, OnInit } from '@angular/core';
import 'intl-tel-input';
import * as jQuery from 'jquery';

@Directive({
  selector: '[appIntlTelInput]'
})
export class IntlTelInputDirective implements OnInit {

  @Input('appIntlTelInput') appIntlTelInput: any;
  constructor(private el: ElementRef) { }

  ngOnInit() {
    // jQuery.fn.intlTelInput.loadUtils('https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.12/js/utils.js');
    // jQuery.fn.intlTelInput.loadUtils('/intl-tel-input/build/js/utils.js');
    jQuery.fn.intlTelInput.loadUtils('assets/js/utils.js');
    jQuery(this.el.nativeElement).intlTelInput(this.appIntlTelInput);
  }
}

表单内的用法

 <intl-tel-input formControlName="Mobile" ></intl-tel-input>

希望这能解决您的问题。它可以根据需要验证任何国际手机号码。