web-dev-qa-db-ja.com

複数のValidators.patternを区別する方法

ユーザーが経度を入力する必要がある入力があります。ユーザーがNaNまたは_Not-Precise-Enough_の値を入力したときに別のエラーメッセージを表示できるようにしたい。検証でエラーを取得するためにFormControl.hasError('ValidatorsName')を使用していますが、これらのパターンを区別できないようです。

テンプレート:

_<mat-form-field class="form-field">
    <input matInput placeholder="Logitude" [formControl]="longitude">
    <mat-error *ngIf="longitude.hasError('pattern')">
        Longitude must be <strong>a number</strong>
    </mat-error>
    <!-- I want to be able to check patter2 for example -->
    <mat-error *ngIf="longitude.hasError('pattern')"> 
        Longitude must have <strong>a minimum of 5 decimal numbers</strong>
    </mat-error>
</mat-form-field>
_

そして私のAngularコード:

_this.longitude = new FormControl(this.attraction.longitude, [
    // is valid number
    Validators.pattern(new RegExp('(\d{1,3})([.|,]{,1})(\d+))','gi')),
    // is precise enough
    Validators.pattern(new RegExp('(\-{0,1})(\d{1,3})([.|,]{1})(\d{5,13})','i'))
]);
_

それらのパターンに識別子を与える方法はありますか?どんな助けにも感謝します。

7
Dawid Zbiński

残念ながら、バリデーターにカスタム識別子を与えることはできません。

更新17.02.2018 21:00

Dawid Zbinskiがコメントで言及しているように、同じエラー(たとえば、「パターン」)を持つ複数のエラーがオーバーライドされると、私は回答を更新しました。

正規表現と事前定義されたエラーを引数として渡すカスタムバリデーターを作成します。

  regexValidator(regex: RegExp, error: ValidationErrors): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} => {
      if (!control.value) {
        return null;
      }
      const valid = regex.test(control.value);
      return valid ? null : error;
    };
  }

次のように使用します。

  this.longitude = new FormControl('', [
    this.regexValidator(new RegExp('^[0-9]+$'), {'number': ''}),
    this.regexValidator(new RegExp('^.{5,}$'), {'precision': ''})
  ]);
  <mat-form-field class="form-field">
    <input matInput placeholder="Logitude" [formControl]="longitude">
    <mat-error *ngIf="longitude.hasError('number')">
        Longitude must be <strong>a number</strong>
    </mat-error>
    <!-- I want to be able to check patter2 for example -->
    <mat-error *ngIf="longitude.hasError('precision')">
        Longitude must have <strong>a minimum of 5 decimal numbers</strong>
    </mat-error>
</mat-form-field>

私はまた、stackblitzデモを更新しました: https://stackblitz.com/edit/angular-dvwcj3?file=app%2Fhello.component.ts

古い回答:

しかし、PatternValidatorsは一意のValidatonErrorObjectsを返します。

official angular repo のパターンバリデーターからソースコードをチェックアウトすると、常にエラーオブジェクト内の正規表現を返すことがわかります。

return (control: AbstractControl): ValidationErrors | null => {
  if (isEmptyInputValue(control.value)) {
    return null;  // don't validate empty values to allow optional controls
  }
  const value: string = control.value;
  return regex.test(value) ? null :
                             {'pattern': {'requiredPattern': regexStr, 'actualValue': value}};
};

これを念頭に置いて、component.tsファイル内に2つのゲッターメソッドを簡単に作成できます。そして、それらは2つの正規表現の間で異なります。この例では、一意の部分文字列が正規表現に一致するかどうかを確認するだけです。確かに、これらはこれを処理する他の方法です。

  get numberError() {
    if (this.longitude && this.longitude.hasError('pattern')) {
      return this.longitude.getError('pattern').requiredPattern.indexOf('(\d+)') !== -1
    }
    return false;
  }

  get preciseError() {
    if (this.longitude && this.longitude.hasError('pattern')) {
      return this.longitude.getError('pattern').requiredPattern.indexOf('(\-{0,1})') !== -1
    }
    return false;
  }
8
SplitterAlex