Angular: FormControl.setValidators ... getValidatorsがないのはなぜですか

䜜成日 2016幎12月14日  Â·  72コメント  Â·  ゜ヌス: angular/angular

送信しおいたす... 「x」でチェックしおください

[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

珟圚の動䜜
TypeScript FormBuilderを介したReactiveFormにrequired、maxLengthのような基本的なバリデヌタヌを備えたAbstractControlがありたす。 これらの基本的なバリデヌタヌに、ドロップダりン倀に基づいお怜蚌戊略を動的に倉曎するカスタムバリデヌタヌを远加したした。 珟圚、別のコンポヌネント内setValidators()メ゜ッドを䜿甚しおいたすAbstractControlは@Input()を介しお含たれおいたす。 䞻な問題は、既存のバリデヌタヌを䞊曞きするこずです。
䟋

アプリコンポヌネント

this.formBuilder.group({
      zip: ['', [Validators.required, Validators.maxLength(10)]] 
    });

アプリテンプレヌト

<zip ...
        [control]="form.controls.zip">
</zip>

ZIPコンポヌネント

@Input() control: AbstractControl;

this.control.setValidators([
      // redundant to formBuilder
      Validators.required,
      Validators.maxLength(10),
      // custom validation based on a dropdown value (via. valueChange Detection)
      validateZipFn(countryCode)]
    );

予想される行動
柔軟性を維持するために、すべおのバリデヌタヌを䞊曞きしたくありたせん。 以䞋のコヌドは、 getValidators()メ゜ッドの動䜜を瀺しおいたす。

アプリコンポヌネント

this.formBuilder.group({
      zip: ['', [Validators.required, Validators.maxLength(10)]]
    });

アプリテンプレヌト

<zip ...
        [control]="form.controls.zip">
</zip>

ZIPコンポヌネント

@Input() control: AbstractControl;

let listOfAllValidationRules = this.control.getValidators().push(validateZipFn(countryCode)]);
this.control.setValidators(listOfAllValidationRules);

行動を倉える動機/ナヌスケヌスは䜕ですか
動的怜蚌により柔軟になりたす。

  • Angularバヌゞョン 〜2.1.2

  • ブラりザすべお

  • 蚀語 TypeScript / ES6

forms feature medium

最も参考になるコメント

私は同意したす。珟圚のコントロヌルのメ゜ッドで取埗できるバリデヌタヌの読み取り専甚リストがあるず非垞に圹立ちたす。

党おのコメント72件

@Icepick返すものは䜕もありたせん。 バリデヌタヌは、配列ではなく単䞀のオブゞェクトずしお栌玍されたす。

@DzmitryShylovichこれは実装できないずいう意味ですか 個人的には、メタデヌタが添付されたバリデヌタヌの読み取り専甚コピヌのみが必芁です。

怜蚌メッセヌゞのオブゞェクトが枡されるディレクティブを䜜成しおいたす。これは、怜蚌ルヌル名がキヌで、倀が衚瀺されるメッセヌゞであるオブゞェクトです。 このオブゞェクトずNgControlのセットバリデヌタヌを比范しお、特定のメッセヌゞが欠萜しおいる堎合にナヌザヌに譊告するようにしたす。

@Bidthedogず同様の理由でこれも芋たいです。 たずえば、 Validator.requriedがコントロヌル䞊にある堎合、これをプログラムでフォヌムに瀺したす。 必芁なのは読み取り専甚です。 珟圚私ができる最善のこずは、コンポヌネントに配列を定矩し、それをフォヌムコントロヌル定矩に枡すこずです。 それはかなりすぐに醜くなるでしょう

これはロヌドマップにありたすかある堎合、この機胜にETAはありたすか

その通り。 私のフォヌムサヌビスには、基本的に3぀の倧きな厄介な重耇定矩がありたす。 以䞋のコヌドスニペットは、私がたずめおいるかなり倧きな6ペヌゞのフォヌムからの小さな抜粋です。 これは、1ペヌゞ目詳现ず2ペヌゞ目医療の始たりです。

䜜成/定矩するには

  private createForm() {
    this.form = this.fb.group({
      details: this.fb.group({
        NHSNumber: [null, [Validators.required, Validators.pattern(/^\d{3}-\d{3}-\d{4}$/)]],
        titleId: [null, [Validators.required]],
        firstName: [null, [Validators.required, Validators.maxLength(10)]],
        middleNames: null,
        lastName: [null, [Validators.required]],
        DOB: [null, [Validators.required]],
        genderId: [null, [Validators.required]],
        regionId: [null, [Validators.required]],
        maritalStatusId: [null, [Validators.required]],
        occupationTypeId: [null],
        occupationId: null,
        telephoneNo: null,
        mobileNo: null,
        houseNumber: null,
        streetName: null,
        town: null,
        city: null,
        county: null,
        postcode: null,
        GPId: null,
        nextOfKinId: null,
        livesWith: null
        //vehicleLicenseTypeId?: number[]
      }),
      medical: this.fb.group({
        gpId: [null, [Validators.required]]
      })
    });
  }

移入するには

  private populateForm() {
    let m = this.model;
    this.form.setValue({
      details: {
        NHSNumber: this.getTextValue(m.NHSNumber),
        titleId: this.getLookupValue(m.titleId),
        firstName: this.getTextValue(m.firstName),
        middleNames: this.getTextValue(m.middleNames),
        lastName: this.getTextValue(m.lastName),
        DOB: this.getDateValue(m.DOB),
        genderId: this.getLookupValue(m.genderId),
        regionId: this.getLookupValue(m.regionId),
        maritalStatusId: this.getLookupValue(m.maritalStatusId),
        occupationTypeId: this.getLookupValue(m.occupationTypeId),
        occupationId: this.getLookupValue(m.occupationId),
        telephoneNo: this.getTextValue(m.telephoneNo),
        mobileNo: this.getTextValue(m.mobileNo),
        houseNumber: this.getTextValue(m.houseNumber),
        streetName: this.getTextValue(m.streetName),
        town: this.getTextValue(m.town),
        city: this.getTextValue(m.city),
        county: this.getTextValue(m.county),
        postcode: this.getTextValue(m.postcode),
        GPId: this.getLookupValue(m.GPId),
        nextOfKinId: this.getLookupValue(m.nextOfKinId),
        livesWith: this.getTextValue(m.livesWith)
      },
      medical: {
        gpId: this.getLookupValue(m.GPId) || 1
      }
    });

怜蚌ルヌル。 完党ではありたせんが、これがどのように乱雑になり、速くなるかがわかりたす

  private formValidationMessages = {
    details: {
      NHSNumber: {
        required: '\'NHS Number\' is required',
        pattern: '\'NHS Number\' must be in the format \'NNN-NNN-NNNN\' where N is a digit'
      },
      titleId: {
        required: '\'Title\' is required'
      },
      firstName: {
        required: '\'First Name\' is required'
      }
    },
    medical: {
    }
  };

私は1぀のオブゞェクトセットですべおのフォヌムルヌルを定矩する䜜業を開始したした。これは、䞊蚘の関数を繰り返し凊理/投圱するこずを考えおいたすただそれほど進んでいたせんが。

  private formValidationMessages = {
    details: {
      NHSNumber: {
        required: '\'NHS Number\' is required',
        pattern: '\'NHS Number\' must be in the format \'NNN-NNN-NNNN\' where N is a digit'
      },
      titleId: {
        required: '\'Title\' is required'
      },
      firstName: {
        required: '\'First Name\' is required'
      }
    },
    medical: {
    }
  };

もちろん、これに加えお、デヌタモデルの定矩があり、次にバック゚ンドのすべおのレむダヌがありたす。 コヌドの膚匵を枛らすために私たちにできるこずがあるはずですか

たた、FormControl甚に構成されたバリデヌタヌを取埗できないこずにも芋舞われたした。

FormBuilderに枡される前に構成オブゞェクトをラップし、コントロヌル名ず指定されたバリデヌタヌの間のマッピングを远跡するナヌティリティサヌビスを远加するこずで、この問題を回避したした。

この远加サヌビスの必芁性を取り陀くこずは圓然玠晎らしいこずです😄

ここに投皿しおから、すべおのフォヌム構成を1぀の倧きなオブゞェクトに統合し、構成に基づいおフォヌムずモデル間のマッピングを行ういく぀かのヘルパヌメ゜ッドを䜜成したした。 それはすべおあたりにも耇雑に思えたすが、それは私が持っおいた孊習曲線である可胜性がありたす。

こんにちは、
この機胜に぀いお䜕か蚀葉があるかどうか疑問に思っおいたす。 特定のアむテムを必芁に応じお芖芚的にマヌクできるこずは、最新のフォヌムUIに期埅される基本的な機胜のように思えたす。 ただし、フィヌルドが必須かどうかに関係なく情報を取埗する方法がないため、リアクティブフォヌムを䜿甚しおこの機胜を実装するこずはできたせん。

それは䞍可胜ではありたせん、それはただたくさんの仕事です。

@Bidthegodは、この機胜をAngularで実装するのは倧倉な䜜業になるのでしょうか、それずもAngularコンポヌネントでバリデヌタヌを取埗するのは倧倉な䜜業になるのでしょうか。

コンポヌネント内のバリデヌタヌを取埗できる堎合は、その方法に関する入力を歓迎したす。

たたは、特定のコンポヌネントタむプ入力、遞択の方が簡単な堎合は、それも圹立ちたす。

@Toub私がやったこずは、すべおの個々のフォヌムフィヌルドずそのすべおの蚭定衚瀺、バリデヌタヌ、ルヌルなどを含む「config」オブゞェクト構造を構築するこずでした。 次に、FormGroupを構築する構成を照䌚するためのいく぀かのヘルパヌメ゜ッドを䜜成したした。 各フォヌムにはフォヌムサヌビスがあり、基本コンポヌネントから継承したす。

簡単な修正ずは蚀えたせんし、倧量のコヌドもありたすが、かなり゚レガントで、かなり耇雑なフォヌムを簡単に䜜成できるようになりたした。 あなたが芋るために芁点でコヌドのいく぀かを投げたした、しかし私は今のずころそれを適切にモゞュヌル化する時間がありたせん。 私が曞いたすべおのカスタムフォヌム入力コンポヌネントを含め、これにはかなりの数のファむルがありたせん。

https://gist.github.com/Bidthedog/1dc7d10cda1759061c09f44f7b48cbf3

@Bidthedogそれは私のニヌズに応えたせんが、芁点は他の人にも圹立぀ので、あなたの答えに感謝したす。

やあみんな、私はバリデヌタヌを返すための簡単なヘルパヌを䜜成したした必芁なだけですが、他の人のために拡匵するこずができたす

getValidators(_f) {
  return Object.keys(_f).reduce((a, b) => {
    const v = _f[b][1];
    if (v && (v === Validators.required || v.indexOf(Validators.required) > -1)) {
      if (!a[b]) { a[b] = {}; }
      a[b]['required'] = true;
    }
    return a;
  }, {});
}

const _f = {
  id: [],
  name: [null, Validators.required],
  phone: [],
  email: [null, [Validators.required, Validators.email]]
};
this.frmMain = this._fb.group(_f);
console.log(this.getValidators(_f));    // {name: {"required": true}, email: {"required": true}}

私のニヌズに合いたす👍

私は同意したす。珟圚のコントロヌルのメ゜ッドで取埗できるバリデヌタヌの読み取り専甚リストがあるず非垞に圹立ちたす。

この機胜の+1

読み取り専甚リストの堎合は+1

+1

すでに存圚するバリデヌタヌを倱うこずなく動的にバリデヌタヌを远加するには、その機胜が必芁です。 䜕かのようなもの
Object.keys(this.myForm.controls).forEach(key => { if (map.get(key)) { this.myForm.get(key).setValidators(this.myForm.get(key).getValidators().push(Validators.required)) } });
完党に説明されおいる https //stackoverflow.com/questions/46852063/how-to-dynamically-add-validators-to-the-forms-in-angular-2-4-using-formbuilde。
これは䞀般的なものでなければなりたせん

実際、composeValidatorshttps://github.com/angular/angular/blob/master/packages/forms/src/directives/shared.ts#L139を䜿甚しおバリデヌタヌを動的に远加するこずはそれほど難しくありたせん。 バリデヌタヌの削陀がより倧きな問題だず思いたす。 ブヌル倀でそれを行うこずができたすが、バリデヌタヌはもはや玔粋関数ではありたせん。

この関数は、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;
    };

@mtinnerそれは本圓に玠晎らしい発芋でした。 それは私に初期セットを取埗しおいたす。 オブザヌバブルのバリデヌタヌを返すこずができるように、APIに远加する䟡倀はただあるず思いたす。 そうすれば、条件付きの必須コントロヌルを芋぀けるのは非垞に簡単です。 ここで提案されおいる回避策を適甚しお、これらのむンスタンスをキャッチできるかどうかはわかりたせん。

Angular Connect 2017の非垞に玠晎らしいプレれンテヌションで、 @ karaは「カスタムフォヌムコントロヌルは玠晎らしく、怖くない」ず蚀っお終了したす。 良いですが、カスタムコントロヌルのこの重芁な機胜がありたせん

+1

PRの時間はありたせんが、これが私が思い぀いたものです

import {FormControl} from '@angular/forms';
import {AsyncValidatorFn, ValidatorFn} from '@angular/forms/src/directives/validators';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';
import {AbstractControlOptions} from '@angular/forms/src/model';

export class DescendingFormControl extends FormControl {

    private asyncValidationChangesSubject = new Subject<AsyncValidatorFn | AsyncValidatorFn[]>();
    private validationChangesSubject = new Subject<ValidatorFn | ValidatorFn[] | null>();

    public readonly validationChanges: Observable<ValidatorFn | ValidatorFn[] | null>;
    public readonly asyncValidationChanges: Observable<AsyncValidatorFn | AsyncValidatorFn[]>;

    constructor(formState?: any, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) {
        super(formState, validatorOrOpts, asyncValidator);
        this.validationChanges = this.validationChangesSubject.asObservable();
        this.asyncValidationChanges = this.asyncValidationChangesSubject.asObservable();
    }

    public setValidators(newValidator: ValidatorFn | ValidatorFn[] | null): void {
        super.setValidators(newValidator);
        this.validationChangesSubject.next(newValidator);
    }

    public setAsyncValidators(newValidator: AsyncValidatorFn | AsyncValidatorFn[]): void {
        super.setAsyncValidators(newValidator);
        this.asyncValidationChangesSubject.next(newValidator);
    }
}

私が自由な時間を埗る前に誰かがPRの仕事党䜓をやろうずしおいるなら、それのために行っおください

+1

+1

+1

問題閉じ蟌められおいる

珟圚のバリデヌタヌの配列は存圚したすが、私たちには利甚できたせん...
バリデヌタヌの静的メ゜ッドcomposeを芋おください。これは、フォヌムコントロヌルでバリデヌタヌの配列を定矩するずきに舞台裏で䜿甚されるメ゜ッドです。

 static compose(validators: (ValidatorFn|null|undefined)[]|null): ValidatorFn|null {
    if (!validators) return null;

    // Here it is
    const presentValidators: ValidatorFn[] = validators.filter(isPresent) as any; 

    if (presentValidators.length == 0) return null;

    return function(control: AbstractControl) {
      return _mergeErrors(_executeValidators(control, presentValidators));
    };
  }

https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts#L342

ご芧のずおり、 presentValidatorsは私たちが探しおいるものですが、クロヌゞャに_トラップ_されおいるためアクセスできず、 composeから取埗した倀のみが、トリガヌされたすべおの゚ラヌを含むオブゞェクトです。䞎えられた倀。

したがっお、バリデヌタヌを掚枬する唯䞀の方法は、フォヌムコントロヌルで゚ラヌを手動でトリガヌするこずです。これにより、バリデヌタヌの名前が参照されたす。

ハック別のコントロヌルで゚ラヌをトリガヌする

バむンドされたフォヌムコントロヌルで゚ラヌをトリガヌしたくない。 代わりに、テンプレヌトぞのバむンドがない新しいフォヌムコントロヌルを䜜成し、同じValidator関数を適甚しおから、倀を蚭定しお必芁な゚ラヌをトリガヌする必芁がありたす。

// Your form control, actually binded to a form in your template

emailControl = new FormControl('', [Validators.required, Validators.email])

// Elsewhere in your code
// You use dummy form controls, on which you apply your original form control validators and various values, to trigger the errors.

const errorsWhenEmpty = new FormControl('', this.emailControl.validator, this.emailControl.asyncValidator).errors
const errorsWhenOneChar = new FormControl('x', this.emailControl.validator, this.emailControl.asyncValidator).errors

// Or you can simply reuse the first dummy control with `setValue()`

理想からはほど遠いですが、バリデヌタヌ自䜓を手に入れるこずができるたでは、私が芋぀けた䞭で最も汚い方法ではありたせん。

FormControlクラスから拡匵し、子クラスのフィヌルドに、コンストラクタヌに枡されたValidator関数のコピヌを保存するこずをお勧めしたす。次のようになりたす。

export class ExtFormControl extends FormControl {
  private _syncValidators: ValidatorFn | ValidatorFn[];

  private _asyncValidators: AsyncValidatorFn | AsyncValidatorFn[];

  constructor(formState?: any, validatorOrOpts?: ValidatorFn | ValidatorFn[] | null,
              asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null) {
    super(formState, validatorOrOpts, asyncValidators);
    this._syncValidators = validatorOrOpts;
    this._asyncValidators = asyncValidators;
  }


  getSyncValidators(): ValidatorFn[] {
    if (typeof this._syncValidators === 'function') {
      return [this._syncValidators];
    } else {
      return this._syncValidators;
    }
  }

  getAsyncValidators(): AsyncValidatorFn[] {
    if (typeof this._asyncValidators === 'function') {
      return [this._asyncValidators];
    } else {
      return this._asyncValidators;
    }
  }

  setValidators(newValidator: ValidatorFn | ValidatorFn[] | null): void {
    super.setValidators(newValidator);
    this._syncValidators = newValidator;
  }

  setAsyncValidators(newValidator: AsyncValidatorFn | AsyncValidatorFn[] | null): void {
    super.setAsyncValidators(newValidator);
    this._asyncValidators = newValidator;
  }

}

私はすべお、バリデヌタヌの読み取り専甚リストを求めおいたす。 ReactiveFormsを䜿甚しお、テンプレヌトではなくFormBuilderコヌドを介しおmaxLengthなどの制玄を構成するこずが期埅される堎合がありたす。 ただし、珟圚、いく぀かの動䜜フォヌカスを次のフィヌルドに移動する、クレゞットカヌド入力の䞀般的なケヌスなどを定矩したり、必芁に応じおラベルを自動的にマヌクしたりするために、HTMLにmaxlengthを配眮する必芁がありたす。

フォヌムに入力されるず曎新されるバリデヌタヌをプログラムで蚭定する必芁がありたす。FormControlでバリデヌタヌを読み取れるず非垞に䟿利です。 私は@moniuchに同意したす。ReactiveFormsを䜿甚するず、これが可胜になるず期埅されたす。 それが実装されるこずを願っおいたす。

曎新はありたすか

うヌん、 1985幎にこの化合物が興味深い問題だず思っおいたす1
セットされたバリデヌタヌを確認したり、優先順䜍を付けたりするこずはできたせん。 :(

コントロヌルの「validator」プロパティを確認しお解決したした。 それはACTIVEバリデヌタヌでオブゞェクトを返したす。 バリデヌタヌが蚭定されおいお、バリデヌタヌが真で​​あるための条件が満たされおいる堎合。
私の䟋では、ネストされたコンポヌネントで䜿甚されるリアクティブフォヌムですらありたす。

芪コンポヌネント

PARENTコンポヌネントのReactiveFormGroupのバリデヌタヌ

return this.formBuilder.group({
      username: ['', [Validators.required, Validators.min(3), Validators.email]],
     ...
});

名前はテストのみを目的ずしおいたす

<app-input name="txtfield" 
[parentForm]="loginForm" parentFormControlName="txtfield" 
></app-input>

ネストされたコンポヌネント

 <div [formGroup]="parentForm" class="form-control-group">
   ...
        <input #inputField  name="{{parentFormControlName}}" 
            formControlName="{{parentFormControlName}}" 
            matInput 
            placeholder="{{placeholderTxt}}"
        >
  ...
    </div>

ネストされたコンポヌネントでは、「必須」のバリデヌタヌのみが必芁なため、AfterViewIinitの埌に䞀床だけチェックしたす。

ngAfterViewInit() {
    // Lookup if this field is required or not
    if (this.parentForm.controls[this.parentFormControlName].validator != null) {
    // MAYBE CHECK FOR required field in returned OBJECT!!
      console.log('Validators of ' + this.parentFormControlName + ' = ', 
           JSON.stringify(
             this.parentForm.controls[this.parentFormControlName]
                      .validator(this.parentForm.controls['username']);)
            );

    } else {
      console.log('No validator set for component ' + this.parentFormControlName); 
    }

デバッガヌが停止しおいる間のブラりザヌコン゜ヌルでの出力

[DEBUG] STATUS of username =  {"required":true}
>this.parentForm.controls[this.parentFormControlName].validator(this.parentForm.controls[this.parentFormControlName])
{required: true}
required: true
__proto__: Object

それ以倖の堎合-バリデヌタヌが蚭定されおいない堎合-「null」ず衚瀺されたす

その他の状況

入力テキストフィヌルドにデフォルト倀がある堎合

input-text-fieldにデフォルト倀がある堎合、これは必須倀がtrueであるこずを瀺したせんが、フィヌルドが必須であり、入力されおいない堎合にのみ、フィヌルド=倪字の行を匷調衚瀺したす。

必芁な倀以倖

「DoCheck」たたは「OnChanges」を䜿甚しお倉曎を監芖し、必芁に応じお「email」たたは「min」バリデヌタヌを取埗する堎合は、他のバリデヌタヌステヌタスをい぀でも確認できたす。

@Angularチヌム、珟圚のバリデヌタヌリストをチェックし、実行時に特定のバリデヌタヌを削陀するAPIが本圓に必芁です。 これは倚くの問題を解決したす。

なぜ「control.errors」ず「controls.validators」がpreatymutchを同じこずをしおいるのですか
「 .errors 」は、゚ラヌ状態に達するよりもすべおの゚ラヌを衚瀺する必芁がありたす。
「 .validators 」は、このコントロヌルのために、登録されおいるすべおのバリデヌタヌを返す必芁がありたす。
それず同じくらい簡単ですか

この機胜も芋たいです。 しかし 私が芋おいる倧きな問題の1぀は、バリデヌタヌが通垞は玔粋関数であるずいうこずです。぀たり、バリデヌタヌは深くネストするこずもできたす。

私たちのプロゞェクトには、他のバリデヌタヌなどから構築されたドメむン関連のバリデヌタヌがたくさんありたす。 たずえば、私たちのIBANバリデヌタヌは、 exactLength 、 pattern 、および内郚でIBANチェックディゞットバリデヌタヌを䜿甚したす。 このパタヌンに埓うず、より具䜓的な怜蚌゚ラヌが発生し、問題をより詳现に説明する゚ラヌメッセヌゞを䜿甚できるようになりたすナヌザビリティにずっおはより良い。

したがっお、すべおのバリデヌタヌを取埗するための新しい方法を怜蚎する堎合、質問は次のずおりです。「䞊䜍のバリデヌタヌ」のみが返されたすか さらに、それらのバリデヌタヌの名前は䜕ですか 党䜓ずしお、珟圚の怜蚌の実装では、簡単な解決策はないように思われたす...

TL; DRAngularフォヌムモゞュヌルの倚くのものを倉曎し、既存のコヌドを壊さずにそれは䞍可胜です。

皆さん、関連する゜ヌスコヌドは次のずおりです。
packages / forms / src / model.ts
packages / forms / src / validators.ts
そしお倚分packages / forms / src / directives / validators.ts

次の問題が芋぀かりたした。

  • たず第䞀に、バリデヌタヌはそれを識別する方法のない単なる愚かな関数オブゞェクトです。 関数の配列を取埗できたずしおも、それではどうしたすか 正芏衚珟バリデヌタヌが単なる関数である堎合、どのようにしお正芏衚珟バリデヌタヌを削陀できたすか これが正芏衚珟バリデヌタヌであるこずを識別する方法が必芁です。これらを远加たたは個別に削陀する堎合は、これが必須のバリデヌタヌです。 したがっお、 addValidator関数を実装するこずはできたすが、 removeValidator関数を実装するこずはできたせん。
  • 次に、 setValidatorsを実行するず、compose関数が最終的に呌び出されたす。 すべおのバリデヌタヌ関数を1぀の関数にたずめ、内郚の_executeValidators関数を呌び出しお実際に呌び出したす。 したがっお、最終的には元のバリデヌタヌの配列がなく、すべおの゚ラヌのリストがマヌゞされた巚倧なメガバリデヌタヌしかありたせん。

そのこずから、バリデヌタヌの抂念にいく぀かの重倧な倉曎を導入せずにgetValidatorsたたはremoveValidatorを実装するこずは䞍可胜であるず結論付けたした。 addValidatorsを実装するこずは可胜のようですが、バリデヌタヌを远加するこずしかできず、既存のバリデヌタヌを削陀できない堎合、誰がそれを必芁ずしたすか

では、アプリに条件付きの動的怜蚌を実装する堎合、たずえば、既存のすべおのメヌルバリデヌタヌを倱うこずなくこのチェックボックスが蚭定されおいる堎合にこのメヌルフィヌルドを必須にする堎合は、どうすればよいでしょうか。 私は2぀のアプロヌチを芋぀けたした

  • フィヌルドのデフォルトのバリデヌタヌを倉数のどこかに保存できたす。 メヌルを必須にするずきは、 setValidator関数を䜿甚しお、Validator.required +すべおのデフォルトのバリデヌタヌを枡したす。
  • フォヌムコントロヌルに必芁なバリデヌタヌを䜿甚する代わりに、チェックボックスずフィヌルドの倉曎の䞡方を監芖するフォヌムグルヌプバリデヌタヌを䜜成できたす。 チェックボックスがtrueに蚭定されおいる堎合、電子メヌルフィヌルドが必須であるかのように動䜜したす。

@ ganqqwerty  正解です。 これが、 addValidator(...)たたはremoveValidator(...)が存圚しない理由です。 識別はありたせん。 バリデヌタヌ自䜓は、どのコントロヌルが実行されおいるかを知りたせん。

@ganqqwertyこれを実装するのが簡単だず蚀っおいるわけではありたせんが、ここではあなたの掚論が有効ではないず思いたす。

正芏衚珟バリデヌタヌをどのように削陀できたすか

バリデヌタヌぞの参照を枡すこずによっお。 むベントリスナヌを削陀するのず同じ方法です。

したがっお、最終的には元のバリデヌタヌの配列がありたせん

これは単なる内郚蚭蚈の決定であり、珟圚、パブリックAPIのどこにも公開されおいたせん。 関数を䜕床も䜜成するのではなく、元の配列を保持するこずを遞択するず、バリデヌタヌの配列をクロヌゞャヌに保持する必芁がある远加の関数がないため、実際にはパフォヌマンス䞊の利点がありたす。

既存のすべおの電子メヌルバリデヌタヌを倱うこずなくこのチェックボックスが蚭定されおいる堎合にこの電子メヌルフィヌルドを必須にするには[...]フォヌム制埡必須バリデヌタヌを䜿甚する代わりに、チェックボックスずフィヌルドの倉曎の䞡方を監芖するフォヌムグルヌプバリデヌタヌを䜜成できたす。

これは意図された動䜜ではありたせんか 電子メヌルフィヌルドを䜿甚したフォヌムコントロヌルは、有効な電子メヌルアドレスがあればそれ自䜓で有効です。 チェックボックスの倀がtrueの堎合、電子メヌルが存圚する堎合、_group_は有効です。 これはバリデヌタヌの回避策ではありたせんが、フォヌムの正しいレベルでの適切な䜿甚法です。

これを明確にしおくれおありがずう そのような機胜の実装をスケゞュヌルできるずいうこずですか

バリデヌタヌぞの参照を枡すこずによっお。

したがっお、バリデヌタヌぞの参照を保持するず、それを削陀するこずが可胜になりたす。 バリデヌタヌずしお無名関数を提䟛するだけでは、それを削陀するこずはできたせん。 うヌん、確かにそれはremoveEventListenerのように芋えたす

この機胜がないず、特定のコントロヌルから特定のバリデヌタヌを削陀するこずはできたせん。

これは私が今必芁ずしおいるものであり、私はこれを解決するこずはできたせん。 非垞に基本的なものがAngularでは䞍可胜な堎合がありたす。

this.myAbstractFormControl.removeValidatorAndKeepTheRestAsIs(Validators.required)

@andreElricoバリデヌタヌを削陀するためのナヌスケヌスは䜕ですか これに぀いお考えれば考えるほど、フォヌムのバリデヌタヌを倉曎するこずの意味がわかりにくくなりたす。 フォヌムの別のフィヌルドに基づいおバリデヌタヌを動的に倉曎する必芁がある堎合、バリデヌタヌの配眮は間違っおいたす。必芁なのは、フォヌムコントロヌルバリデヌタヌではなく、フォヌムグルヌプバリデヌタヌです。

たずえば、2぀のシナリオで動的に入力を介しお提䟛されるのず同じformGroupを䜿甚しようずしおいたす。 1぀は各フィヌルドで必芁なものであり、2぀目は必芁なIFが存圚するものを削陀し、atLeastOneFieldバリデヌタヌをformGroupに適甚する堎合です。

これが私のstackblitzImが取り組んでいるずころです。

既存の怜蚌凊理に関しおAngularチヌムが生み出した蚭蚈䞊の欠陥を保護するものがある理由がわかりたせん。
AngularForm-怜蚌はCRUDである必芁がありたす。

@andreElrico私が蚀ったように、フォヌムに盞互に䟝存する怜蚌を持぀2぀の入力がある堎合、バリデヌタヌはフォヌムコントロヌルではなくフォヌムグルヌプにある必芁がありたす。

たずえば、2぀のパスワヌドフィヌルドがある堎合、最初のコントロヌルが倉曎されるたびに2番目のコントロヌルのバリデヌタヌを倉曎しないでください。 代わりに、バリデヌタヌは2぀のパスワヌドフィヌルドを含むグルヌプに移動する必芁がありたす。 各パスワヌドフィヌルドには、パスワヌドが8文字以䞊である必芁があるずいう怜蚌がありたすが、グルヌプには、同じである必芁があるずいうバリデヌタヌがありたす。 それ自䜓では、各パスワヌドフィヌルドは他のパスワヌドフィヌルドの存圚を認識しおいたせん。 グルヌプはそれらを䞀緒に保持したす。

あなたがのようなものを持っおいるなら

( ) a
( ) b
( ) other [ _____ ]

ここで、ナヌザヌが「その他」を遞択した堎合、その暪に入力フィヌルドが必芁です。この堎合も、入力フィヌルドで「必須」のバリデヌタヌを切り替えないでください。 代わりに、フォヌムグルヌプ党䜓を怜蚌する必芁がありたす。ラゞオボタンコントロヌルは「a」、「b」、たたは「other」のいずれかである必芁があり、「other」の堎合は入力フィヌルドが存圚する必芁がありたす。

ラゞオボタンにリスナヌを配眮しおから、ラゞオボタンの倀に基づいお入力フィヌルドの「必須」バリデヌタヌを切り替える必芁はありたせん。

怜蚌にCRUDAPIが必芁だずあなたが信じおいる理由がわかりたせん。 私は䜕も擁護しおいたせん、私は合理的で議論を持っお話しおいるのです。 バリデヌタヌを取埗、削陀、切り替えするためのメ゜ッドを実装すべきではないず蚀っおいるのではありたせん。ここにいるほずんどの人が、実際にはアンチパタヌンであるCRUD怜蚌のナヌスケヌスを持っおいるず蚀っおいたす。 コントロヌルはスタンドアロンナニットであり、存続期間䞭は怜蚌ルヌルを倉曎したせん。 コントロヌルが䟝存しおいる堎合、それらはグルヌプに入れられ、グルヌプが怜蚌されたす。

コメントず時間をありがずう@lazarljubenovic 。
あなたは私のstackblitzをよく芋おいないように感じたす。 1぀のシナリオのformGroupに「ラッピング」ロゞックを適甚しおいたす。 フォヌムには、バリデヌタヌを動的に倉曎する必芁がある2぀の異なるシナリオがありたす。 そしお、formGroupを扱うその「段階」では、バリデヌタヌはすでに「構成」されおいるので、CRUDはありたせんD。

私はこの問題を回避するこずができ、これがい぀か修正されるこずを願っおいたす。
167👍はこの機胜に察する高い芁望を反映しおいるようです。

時間があれば、もっず知りたいです。

「コントロヌルはスタンドアロンナニットであり、存続期間䞭は怜蚌ルヌルを倉曎したせん。」

それに関するリ゜ヌスはありたすか

「コントロヌルが䟝存しおいる堎合、それらはグルヌプに入れられ、グルヌプが怜蚌されたす。」

これは、実際には限界もありたす。

たた、この問題ずは関係ありたせん。
グルヌプがコントロヌルの怜蚌を匕き継ぐ堎合、゚ラヌはグルヌプに蚭定されるため、コントロヌルに芖芚的に反映されたせん。 したがっお、子コントロヌルに察しお手動で゚ラヌを蚭定および削陀する必芁がありたす。 それは*の倧きな苊痛です。

良い週末をお過ごしください。

私は確かに@lazarljubenovicの芋方を理解しおいたす。

ただし、私は、耇雑な構成を必芁ずする非垞に動的なマルチパヌトの゚ンタヌプラむズフォヌムに取り組んでいたす...倚くの非衚瀺/衚瀺、怜蚌芁件の䟝存関係チェヌンなど。

この耇雑さを凊理する方法は、䟝存関係のトリガヌを担圓するフォヌムコントロヌル、グルヌプ、たたは配列でvalueChangesをサブスクラむブし、シナリオごずにsetValidatorsたたはclearValidatorsを䜿甚するこずです。 特定のバリデヌタヌをタヌゲットにする方法がないため、い぀でも適甚される可胜性のある怜蚌ルヌルの各セットを保存し、それらを再適甚したす。 すべおのバリデヌタヌを取埗したり、個々のバリデヌタヌを远加したり、特定のバリデヌタヌを削陀の察象にしたりできるず䟿利です。これは、すべお䞍倉性を念頭に眮いお蚭蚈できるようです。

「コントロヌルはスタンドアロンナニットであり、存続期間䞭は怜蚌ルヌルを倉曎したせん。」

それに関するリ゜ヌスはありたすか

いいえ; それは本圓にフォヌムのデザむンの私の解釈です。

グルヌプがコントロヌルの怜蚌を匕き継ぐ堎合、゚ラヌはグルヌプに蚭定されるため、コントロヌルに芖芚的に反映されたせん。

正盎なずころ、これらの゚ラヌが発生するはずのUIの芳点からも疑わしいです。 2぀のフィヌルドが䞀緒に再生されないが、フォヌムが倧きく離れおいる堎合、゚ラヌをどこに曞き蟌む必芁がありたすか 最初に䞀歩䞋がっおフォヌムのUXを修正する必芁があるように私には思えたす。

もちろん、フォヌムは野獣であり、すべおのナヌスケヌスに適合するわけではありたせん。 _本圓に_クレむゞヌなコントロヌルを備えた非垞に耇雑なフォヌムがある堎合、 @angular/formsはたったく䜿甚したせん。 @angular/formsは、ナヌスケヌスの95をカバヌし、倚くの劎力をかけずにフォヌムをすばやく䜜成できる優れたナヌティリティだず思いたす。

Array#map 、 Array#filter 、 Array#reduceを䜿甚するのが奜きなのず同じように、むンデックス倉数を䜿甚した叀き良きforルヌプが、より耇雑な反埩の最良の゜リュヌションである堎合がありたす。 。

これらのメ゜ッドを远加するのではないこずをもう䞀床明確にしおおきたいず思いたす。 _倧倚数の人がそれらを悪甚するような気がしたす。 倚分それはフットガンでしょう。 繰り返しになりたすが、誰かがそれを誀甚する可胜性があるずいう理由だけで、有甚なものをフレヌムワヌクに远加すべきではないず思いたす。 トむレの氎で歯を磚くこずもできたす。そのため、トむレは犁止されおいたせん。

非垞に耇雑なフォヌムで非垞にクレむゞヌなコントロヌルを䜿甚しおいる堎合は、@ angle / formsをたったく䜿甚したせん。 @ angle / formsは、ナヌスケヌスの95をカバヌし、倚くの劎力をかけずにフォヌムをすばやく䜜成できる優れたナヌティリティだず思いたす。

これはAngularFormsの公匏の垂堎ポゞショニングですか 巚倧なプロゞェクトに圹立぀䞇胜ツヌルずしお考えたした。

非垞に耇雑なフォヌムで非垞にクレむゞヌなコントロヌルを䜿甚しおいる堎合は、@ angle / formsをたったく䜿甚したせん。 @ angle / formsは、ナヌスケヌスの95をカバヌし、倚くの劎力をかけずにフォヌムをすばやく䜜成できる優れたナヌティリティだず思いたす。

これはAngularFormsの公匏の垂堎ポゞショニングですか 巚倧なプロゞェクトに圹立぀䞇胜ツヌルずしお考えたした。

「リアクティブフォヌム」は、怜蚌を完党に制埡できるなど、耇雑で高床にカスタマむズされたナヌスケヌスを察象ずしおいたす;

あなたはそれを完党に制埡するこずができたす。 怜蚌する察象グルヌプたたはコントロヌルを適切に刀別する必芁がありたす。

これは䜕か牜匕力になりたしたか すべおを切り離しおおくために、入力ずしおformGroupのみを䜿甚しおバリデヌタヌを動的に倉曎したいず思いたす!!! リアクティブフォヌムは玠晎らしいですが、これは私の唯䞀の持ちこたえです。

Soooooooooバリデヌタヌを動的に远加するコヌドをナニットテストするにはどうすればよいですか

バリデヌタヌを適甚したコントロヌルを_読み取る_こずができないため、明らかな単䜓テストは機胜しないようです。

_これは機胜したせん_
expect(component.formControl.validators.length).toEqual(2);

曎新
実際、あなたはそれをこのように行うこずができたす。 ただし、バリデヌタヌを読み取る方が明らかに安䟡です。

component.myCtrl.setValue('');
expect(component.myCtrl.errors.required).toBeTrue();

私はリアクティブフォヌムの倧ファンであり、それらを䜿っお䜕ができるかが倧奜きですが、FormControlにバリデヌタヌに぀いお尋ねるこずができないなどの小さなこずは芋萜ずしのようです。 FormControlには非垞に倚くの状態プロパティがあるずするず、少なくずも.requiredプロパティを䜿甚可胜にするこずを劚げるものは䜕ですか これが日垞生掻に圓おはたるず想像しおみおください...

私こんにちは、私は私の玄束のためにここにいたす。
受付申し蚳ありたせんが、お䌚いできたせん。
私どうしお 今、玄束がありたす。
受付係私は知らない肩をすくめる。

少し䞀般化しおいたすが、FormControlプロパティ倀を枡せば、それらの倀にもアクセスできるはずです。

少なくずも.requiredプロパティを利甚可胜にするこずを劚げるもの

独自のrequiredバリデヌタヌを䜜成できるずいう事実。 Angularはあなたの関数が䜕をするのかを知るこずができたせん。

100はそれを理解しおいたす、私はそれが関数に基づいおいるず蚀っおいるのではありたせん。 フィヌルドが必須であるこずを知るこずは、構成可胜でアクセス可胜であり、UIに反映される有効化/無効化を知るこずず同じくらい基本的です。
開発者がFormControlを操䜜するだけで、必芁なマヌカヌを条件付きで衚瀺するなどのこずができるように、必芁なフィヌルドに察しお同様の機胜を取埗できるようにするためにできるこずはありたすか

こんにちは、これは私たちの最新のハックであり、必芁な入力を自動的にマヌクしたす https//stackblitz.com/edit/material-input-auto-required-asterisk。 同じ抂念をmat-selectやその他のラむブラリにも適甚できたす。

const _clearValidators = AbstractControl.prototype.clearValidators;
AbstractControl.prototype.clearValidators = function(){
  (this as any).isRequired = false;
  _clearValidators.call(this);
}

const _setValidators = AbstractControl.prototype.setValidators;
AbstractControl.prototype.setValidators = function(newValidator: ValidatorFn | ValidatorFn[] | null): void {
  (this as any).isRequired = false;
  _setValidators.call(this, newValidator);
}

export function isRequired(control: AbstractControl): ValidationErrors | null{
  (control as any).isRequired = true;
  return Validators.required(control);
}

@Directive({ selector: '[matInput]:not([required])' })
export class MatInputRequiredDirective implements DoCheck {
  constructor(private readonly input: MatInput) { }

  ngDoCheck() {
    const isRequired = (this.input.ngControl && this.input.ngControl.control as any).isRequired || false;
    if(isRequired !== this.input.required){
      this.input.required = isRequired;
      this.input.ngOnChanges();
    }
  }
}

100はそれを理解しおいたす、私はそれが関数に基づいおいるず蚀っおいるのではありたせん。 フィヌルドが必須であるこずを知るこずは、構成可胜でアクセス可胜であり、UIに反映される有効化/無効化を知るこずず同じくらい基本的です。

私はちょっず確信が持おたせん。 「芁件」は、アプリケヌションのビゞネスロゞックに非垞に固有です。 空の文字列は「必須」条件を通過したすか れロはどうですか 耇数遞択の空の配列 チェックボックスが間違っおいたすか ヌル、未定矩

開発者がFormControlを操䜜するだけで、必芁なマヌカヌを条件付きで衚瀺するなどのこずができるように、必芁なフィヌルドに察しお同様の機胜を取埗できるようにするためにできるこずはありたすか

必芁な条件に基づいお、すでに条件付きで゚ラヌを衚瀺/非衚瀺にするこずができたす。 ゚ラヌが存圚するからずいっお、必ずしもどこかに衚瀺する必芁があるずは限りたせん。 ここでは、単に゚ラヌ利甚可胜を照䌚するのではなく、バリデヌタヌを照䌚するこずがどのように圹立぀かわかりたせん。

私はちょっず確信が持おたせん。 「芁件」は、アプリケヌションのビゞネスロゞックに非垞に固有です。 空の文字列は「必須」条件を通過したすか れロはどうですか 耇数遞択の空の配列 チェックボックスが間違っおいたすか ヌル、未定矩

有効/無効になっおいるフィヌルドもアプリケヌションのビゞネスロゞックに非垞に固有であるず䞻匵できたすが、FormControlは、開発者がコンストラクタヌずアクセサヌを介しおそれを管理する機胜を提䟛したす。 必芁ずされるのは曖昧な線であり、私はあなたがどこから来おいるのかを理解したす。 これは個人的な奜みかもしれたせんが、倀の有効性を瀺すのず同じくらい、衚瀺状態有効/無効、有効/無効などです。

必芁な条件に基づいお、すでに条件付きで゚ラヌを衚瀺/非衚瀺にするこずができたす。 ゚ラヌが存圚するからずいっお、必ずしもどこかに衚瀺する必芁があるずは限りたせん。 ここでは、単に゚ラヌ利甚可胜を照䌚するのではなく、バリデヌタヌを照䌚するこずがどのように圹立぀かわかりたせん。

はい、条件付きで゚ラヌを非衚瀺/衚瀺できたすが、これらの゚ラヌが解決されるず、期埅される状態に䟝存しないプレれンテヌション郚分は䜿甚できなくなりたす。 バリデヌタヌに基づいおアスタリスクを衚瀺するこずはできたせん。これらのバリデヌタヌが満たされるず、それらは䜿甚できなくなるためです。
今のずころ、私はそれを回避する必芁があるず思いたす。

有効/無効になっおいるフィヌルドも、アプリケヌションのビゞネスロゞックに非垞に固有です。

方法がわかりたせん。

バリデヌタヌに基づくアスタリスクを衚瀺できたせん

したがっお、代わりに、独自の「必須」セマンティクスに基づいおバリデヌタヌを远加したす。 すべおがワンラむナヌになるわけではありたせん。

私はシナリオをサポヌトするための合理的な方法を探しおいたすが、必ずしもワンラむナヌではありたせん。 私はたた、私のものがずれおいる堎合に備えお、あなたの芖点を理解しようずしおいたす。

私のセマンティクスが単なるバニラであり、Validators.required怜蚌を掻甚するためだけに必芁な堎合はどうなりたすか 以䞋のStackBlitzの䟋では、テキストフィヌルドに远加しお倀を入力した堎合、それを知る唯䞀の方法は、 field.errorsオブゞェクトを介しお、バリデヌタヌに関連付けられたプロパティを探すこずです。 ただし、Validatorが満たされるず、そのプロパティは存圚しなくなりたす。 たぶん私のアプロヌチは間違っおいたすが、FormControlを掻甚しお、私が利甚しおいないこれを達成するためのより良い方法はありたすか

StackBlitzの䟋

別のフィヌルドの有効性に基づいおバリデヌタヌを切り替えるこずは想定されおいたせん。 グルヌプバリデヌタヌを䜜成し、名前ずセカンダリ名の䞡方を含むオブゞェクトの倀を確認したす。 詳现に぀いおは、このコメントを参照しおください。

スタヌに関しおは...たあ、あなたのアプロヌチは「それはひどい考えだ」ずいう意味で「間違っおいる」わけではありたせんが、それはバリデヌタヌが珟圚想定しおいる方法では機胜しない考えです。 ですから、あなたのアプロヌチは、フォヌムが珟圚どのように䜿甚されるず想定されおいるかず_互換性がない_ず蚀いたいです。

説明した効果をすばやく実珟したい堎合は、独自のミニフォヌム䜜成ラむブラリを䜜成する必芁がありたす。 これは、この問題に盎面した堎合に問題にどのように取り組むかに぀いおの簡単なスケッチです。 たずえば、次のようなspecオブゞェクトを受け入れる関数createFormを䜜成できたす。

spec = {
  name: {
    initialValue: '',
    isRequired: (formValue) => true, // always required
  },
  secondName: {
    initialValue: '',
    isRequired: (formValue) => isFilledIn(formValue.name), // required only if name is filled in
  }

isFilledInは、倀が入力されおいるかどうかを刀別する関数です。 おそらくval => val != null && value != ''のようなものです。

このcreateFormは、次のように䜜成した堎合ず同じフォヌムを返したす。

this.fb.group({
  name: [''],
  secondName: [''],
}, {
  validators: [
    (group) => {
      const value = group.value
      const errors = {}
      if (spec.name.isRequired(value) && !isFilled(value.name)) {
        errors['name-required'] = true
      }
      if (spec.secondName.isRequired(value) && !isFilled(value.secondName)) {
        errors['secondName-required'] = true
      }
      return errors // or null if no errors found
    }
  ]
})

゚ラヌはグルヌプ自䜓に発生したす。 secondNameの゚ラヌは確かにそこに属したす。その有効性は別のフィヌルドに䟝存するため、 secondNameを単独で怜蚌するこずはできたせん代わりにそれらのフィヌルドのグルヌプを怜蚌したす。 nameの゚ラヌは$ nameに属するはずですが、この実装のスケッチはそれをフォヌムグルヌプに配眮したす。 これはうたくいくかもしれたせんし、うたくいかないかもしれたせん。 specオブゞェクトにフィヌルドを導入しお、このように構成をさらに埮調敎するこずができたす。

@angular/formsオブゞェクトが手元にあるので、テンプレヌトでは通垞どおりフォヌムを䜿甚したす。 フォヌムグルヌプからの゚ラヌずコントロヌルからの゚ラヌたたは、それが機胜する堎合はグルヌプからのすべおを印刷する必芁がありたす。 スタヌを切り替えるための条件はspec[key].isRequired(form.value)になりたす。

これをどれだけ正確に実装するかずいう可胜性は無限であり、それはすべお、フォヌムAPIがすべおの人を満足させるずは思わないほどの小さな決定に䟝存したす。 したがっお、自分のプロゞェクトでフォヌムに期埅する内容に応じお、フォヌムビルダヌの呚りに「セマンティック」ラッパヌを導入するのが最善です。これにより、芁件に基づいお远加の凊理が実行されたす。

アプロヌチず前のコメントを参照するために時間を費やしおくれおありがずう、スレッドの歎史はかなり長いです:)

それが私の問題の䞀郚だったず思いたす。 グルヌプ化されたコントロヌルずグルヌプ倖に存圚するコントロヌル間のフィヌルドの䟝存関係を適切に管理したす。 スペックアプロヌチはほずんどの分野で私のフォヌルバックでしたので、あなたもそれにアプロヌチする方法であるように思えおうれしいです。

フォヌムAPIがすべおの人を満足させるずは思わない

確かに、提䟛されおいるAPIがその皮のカバレッゞを満たしおいるかどうかはわかりたせん。

すべおのアップデヌト この号の䜜成からほが4幎。
珟圚、怜蚌を保存するためのカスタムナヌティリティ関数を䜜成しおいたす。これは、formControlのgetValidatorsのためだけに「バニラ」角床から掟生しすぎる関数です。

本圓にこの機胜が必芁になりたす

これは、リアクティブフォヌムをラップする䜿甚者にずっお非垞に圹立ちたす

非垞に貎重なスレッド。 ただし、フォヌムコントロヌルのバリデヌタヌにアクセスできないようにするこずで、どのような目的を解決するのかに぀いお少し混乱しおいたす。 私はこの芁件にぶ぀かりたした。カスタムコンポヌネントが必芁な堎合は「*」を衚瀺する必芁があり、そのすぐ䞋に関連する゚ラヌメッセヌゞが衚瀺される可胜性がありたすナヌザヌがそれを垌望する堎合。 もう1぀の方法は、ナヌザヌにテンプレヌトからプロパティを蚭定させるこずで、コントロヌル自䜓のAPIに远加するこずです。 ただし、リアクティブ圢匏の堎合、ナヌザヌが必芁なバリデヌタヌたたはその他のバリデヌタヌを既に提䟛しおいるため、これは必芁ありたせん。 私のカスタムコンポヌネントは、そのようなバリデヌタヌが蚭定されおいるこずを認識でき、それに基づいお芁玠を衚瀺/非衚瀺にできるはずです。 非垞に䞀般的な芁件のようです。

バリデヌタヌに関するすべおの情報を持ち、それらのバリデヌタヌを完党に制埡できるようにするカスタム構成のカスタムFormControlを䜿甚した゜リュヌション

export class CustomFormControl extends FormControl {

  public listValidator: CustomValidator[] = [];

  private constructor(formState?: any,
                      validatorOrOpts?: ValidatorFn | ValidatorFn[] | CustomCtrlOpts | null,
                      asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) {

    super(formState, validatorOrOpts as ValidatorFn[], asyncValidator);

    if (validatorOrOpts instanceof CustomCtrlOpts) {
      this.listValidator = validatorOrOpts.customConf;
    }
  }

  // Builder ith default value
  public static init(formState?: any): CustomFormControl {
    return new CustomFormControl(isNil(formState) ? null : formState);
  }

  public required(): CustomFormControl {
    return this.and('required');
  }

  public email(): CustomFormControl {
    return this.and('email');
  }

  public custom(): CustomFormControl {
    return this.and('custom');
  }

  public min(min: number): CustomFormControl {
    return this.and('min', min);
  }

  public max(max: number): CustomFormControl {
    return this.and('max', max);
  }

  private and(key: TypeCustomValidator, value?: any): CustomFormControl {
    this.listValidator.push({key: key, value: value});
    this.setValidators(new CustomCtrlOpts(this.listValidator).validators as ValidatorFn[]);
    return this;
  }
}

// Add others if needed
export type TypeCustomValidator = 'min' | 'max' | 'required' | 'email' | 'custom' ;

export interface HandledValidator {
  key: TypeCustomValidator;
  function: Function;
  params?: boolean;
}

export const listHandledValidators: HandledValidator[] = [
  {key: 'required', function: Validators.required},
  {key: 'email', function: Validators.email},
  {key: 'min', function: Validators.min, params: true},
  {key: 'max', function: Validators.max, params: true},
  {key: 'custom', function: custom}
];

export interface CustomValidator {
  key: TypeCustomValidator;
  value?: any;
}

export class CustomCtrlOpts implements AbstractControlOptions {

  validators?: ValidatorFn | ValidatorFn[] | null;
  asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null;
  updateOn?: 'change' | 'blur' | 'submit';

  private _customConf?: CustomValidator[];

  constructor(value: CustomValidator[]) {
    this.customConf = value;
  }

  get customConf(): CustomValidator[] {
    return this._customConf;
  }

  set customConf(value: CustomValidator[]) {

    this._customConf = value;

    if (!value) {
      return;
    }

    this.validators = [];

    value.forEach(customValidator => {
      const validator = listHandledValidators.find(it => it.key === customValidator.key);
      if (validator.params) {
        (this.validators as ValidatorFn[]).push(validator.function(customValidator.value) as ValidatorFn);
      } else {
        (this.validators as ValidatorFn[]).push(validator.function as ValidatorFn);
      }
    });
  }
}

次のようなformGroup初期化を䜿甚

this.form = this.fb.group({
    amount: CustomFormControl.init(10).required().min(0), 
    ...

これは本圓に玠晎らしい機胜です。 このための回避策を䜿甚するず、時間の無駄のように感じたす。

本圓にこの機胜が必芁になりたす

ええ、これは本圓に必芁です。 簡単に蚀えば、䜕かを蚭定する方法があるずしたら、それを無効にする同様の方法もあるはずです。 䜕かを簡単に蚭定できるが、それらを取り戻すために倚くの劎力を費やさなければならない堎合、_本圓に必芁な_䜕かが明らかに欠けおいたす。

この問題/機胜に関する進展はありたすか

@BenKatanHighLander途䞭です https //github.com/angular/angular/pull/37263#issuecomment -723333060

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡