web-dev-qa-db-ja.com

Angular2:FormControlにバリデーターが必要かどうかを確認しますか?

必要なバリデーターがコントロールに登録されている場合、誰かがAngular2 FormControlを見つける方法を知っていますか?.

this.form = builder.group({name: ['', Validators.required]};

次に、this.form.controls['name']必須フィールドかどうかを制御しますか?それが有効かどうかを確認できることはわかっていますが、それは私が望んでいることではありません。

敬具、マルク

39
Marc

この関数は、FormGroupsとFormControlsで機能するはずです。

  export const hasRequiredField = (abstractControl: AbstractControl): boolean => {
    if (abstractControl.validator) {
        const validator = abstractControl.validator({}as AbstractControl);
        if (validator && validator.required) {
            return true;
        }
    }
    if (abstractControl['controls']) {
        for (const controlName in abstractControl['controls']) {
            if (abstractControl['controls'][controlName]) {
                if (hasRequiredField(abstractControl['controls'][controlName])) {
                    return true;
                }
            }
        }
    }
    return false;
};
52
Marcel Tinner

Angular requiredバリデーターが特定のフィールドに設定されているかどうかを直接見つけるAPIはありませんが、これを実現するための迂回方法は次のようになります。

import { NgForm, FormControl } from '@angular/forms';

const isRequiredControl = (formGroup: NgForm, controlName: string): boolean => {
    const { controls } = formGroup
    const control = controls[controlName]
    const { validator } = control
    if (validator) {
        const validation = validator(new FormControl())
        return validation !== null && validation.required === true
    }
    return false
}

私はこれをテストしましたが、これはValidator.Requiredバリデーターが特定のFormControlに追加されます。

6
Aragorn

同様の問題があります。今のところ、私はこれを使用しています:

  import { Attribute } from '@angular/core';

  // "Kind-of" hack to allow "pass-through" of the required attribute
  constructor(@Attribute('required') public required) {
    // call super here if the component is an ancestor
  }

「無効」などのプロパティがFormControlに含まれているが、「必須」ではない理由について、私は本当に困惑しています。

2
Dave Nottage

バリデーターをチェックする方法やすべてのバリデーターを取得する方法はありません: https://github.com/angular/angular/issues/13461

@ fairlie-アジャイルソリューションはかなり賢いです。しかし、必要なバリデータを起動する必要があるため、空のFormControlを使用する必要があると思います。this.group.controls[this.config.name]は、すでに何らかの値で初期化されている場合があります。

ngOnInit() {
    let formControl = this.group.controls[this.config.name];
    let errors: any = formControl.validator && formControl.validator(new FormControl());
    this._required = errors !== null && errors.required;
}
2
vlapo21

これを行う1つの方法は、フォームが読み込まれたときにコントロールが有効かどうかをチェックして、必要なエラー(フィールドが空の場合にエラーが発生する)があるかどうかを確認することです。

これは、コントロールが変更されるまで発生しないため、minLengthなどの他のバリデーターでは機能しません。

export class FormInputComponent implements Field, OnInit {
  private _required: boolean;
  config: FieldConfig;
  group: FormGroup;

    /** Readonly properties. */
  get required(): boolean { 
    return this._required;
  }

  ngOnInit() {
    var _validator: any = this.group.controls[this.config.name].validator && this.group.controls[this.config.name].validator(this.group.controls[this.config.name]);
    this._required = _validator && _validator.required;
  }
}
1
Fairlie Agile

最初に登録された唯一のエラーがrequiredエラーであると仮定して

// in your component you'll have access to `this.myFormGroup`
const formGroup = {
  controls: {
    email: {
      errors: {
        required: true
      }
    },
    username: {
      errors: null
    }    
  }
}

// required by default
let required = {
  email: '*',
  username: '*',
};

// in `ngOnInit`
required = Object.entries(formGroup.controls)
  .map(([key, control]) => [key, control.errors])
  .filter(([, errors]) => !errors)
  .map(([key]) => [key, ''])
  .reduce((_required, [key, isRequired]) => Object.assign(_required, { [key]: isRequired }), required)

// in your template you may write `<label>Email{{ required.email }}</label>`
console.log(required)
0
Mateja Petrovic