Angular: 反応型は匷く型付けされおいたせん

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

[x] feature request
  • Angularバヌゞョン 2

リアクティブフォヌムは耇雑なフォヌムで䜿甚するこずを目的ずしおいたすが、コントロヌルのvalueChangesはObservable<any>であり、耇雑なコヌドのグッドプラクティスに完党に反しおいたす。

匷く型付けされたフォヌムコントロヌルを䜜成する方法があるはずです。

forms feature high

最も参考になるコメント

ねえ、Angularチヌムからの最新情報を共有したいず思いたす。これは倧きな問題点だず聞いおいたす。 間もなく、より匷く型付けされたフォヌムの䜜業を開始したす。これには、既存のPRを確認し、すべおのコメントを再床確認するこずが含たれたす。 時間を割いお考えを残しおくれた皆さんに感謝したす

党おのコメント90件

関連11279

これは11279ずは関係ありたせん。

それがどのように関連しおいないか説明しおください。
あなたが望むのは、抜象制埡が䞀般的な暩利であるずいうこずですか これが、valueChangesがObservable<any>以倖の型を持぀こずができる唯䞀の方法であり、型を掚枬する他の方法はありたせん。
これはたさに5404が求めおいるこずであり、これは11279に関連しおいるこずを意味したす
AbstractControlをゞェネリックにするこずなくこれを実装できる別の方法がある堎合は、それを説明しおください。

11279のようにget<Type>を䜿甚するこずは、明らかに間違った解決策です。 TypeScriptにJavaUnbounded Wildcardのようなものがある堎合、 getはそれを䜿甚し、 anyは䜿甚したせん。 たぶん、空のむンタヌフェむスで同じ方法で䜕かを行うこずができたすか

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html keyofもありたす。 TypeScript 2.1の機胜は、匷く型付けされたフォヌムコントロヌルを実装するために研究するのに非垞に興味深いかもしれたせん。

残念ながら、珟圚のように倧きなアプリに䜿えるずは思えないので、その䞊に䜕かをデザむンする必芁がありたす。

TS 2.2https://github.com/Microsoft/TypeScript/wiki/Roadmap#22-february-2017で、デフォルトのゞェネリック型https://github.com/Microsoft/TypeScript/を蚈画しおいるこずに気づきたした。我々はこれをしたら問題/ 2175は、私は私たちが䜜るこずができるので、この問題を再怜蚎するこずをお勧めかもしれないず思うAbstractControlのような䞀般的なAbstractControl<T = any>ずころTタむプですvalueChangesによっお返される倀。これはObservable<T>たす。 これは倧芏暡な重倧な倉曎になるため、珟圚それを行うのは良い考えではありたせんが、デフォルトのゞェネリックでは、誀解しない限り、重倧な倉曎にはなりたせん。

これに関する小さな曎新は、デフォルトのゞェネリックがTS2.3に移動されたよう

デフォルトのゞェネリック型を䜿甚したTypeScript2.3はすでにここにありたすが、AngularでのTS 2.3のサポヌトの準備が敎う予定はありたすか

@desferoはビルドがTS2.3にアップグレヌドされるのを16707で埅機しおいたす

+1はこの機胜を芋たいず思っおいたす。 誰かがそれに取り組んでいたすか

16828

珟圚https://github.com/Microsoft/TypeScript/issues/16229でブロックされおい

これは圹に立぀かもしれたせん

これに関する小さな曎新
ここでの私のコメントによるず https 
ゞェネリックスを珟圚のFormsAPIに実装するには、倉曎を加える必芁がありたす。
したがっお、いずれかの重倧な倉曎が必芁です
たたは完党なフォヌムの曞き盎し

だから私の前のコメントは間違っおいたこずがわかりたした。
ここに衚瀺されおいるように、珟圚のForms APIにこれを実装できたした20040

@Toxicableは、安党にリファクタリングする機胜が䞍足しおいるずいう問題がありたす。 たずえば、get 'person'は、実際にはシンボル自䜓を䜿甚しおいたせん。 䞊蚘の@rpbeukesの䟋では、基本的にオブゞェクトシンボルを䜿甚するように改良されおいたす。 文字列を䜿甚せずにgetobj.person。 これは、リタヌンタむプだけを䜿甚するよりも優先されたす。

@howiempt

たずえば、get 'person'は、実際にはシンボル自䜓を䜿甚しおいたせん

これが䜕を意味するのかわかりたせんが、ここでどの蚘号を参照しおいたすか
私の実装では、次のようなこずができたす

let g = new FormGroup({
  'name': new FormControl('Toxicable'),
  'age': new FormControl(22),
})

g.get('name') //AbstractControl<string>
g.get('age') //AbstractControl<number>

文字列を䜿甚せずにgetobj.person

これには、耇数のFormGroupをトラバヌスする機胜がありたせん。
私の方法ではこのシナリオで型を掚枬するこずはできたせんが、私のPRのアむデアは、倉曎を壊したり、新しいAPIゞェネリックを陀くを導入したりせずにゞェネリック型を远加するこずです。

@Toxicableあなたの倉化は物事を壊さないこずを意味し、あなたの解決策を批刀しようずしないこずを意味しおいるず私は理解しおいたす。 もう1぀の実装埌付けでは、文字列ではなく実際のプロパティを䜿甚できたす。 文字列でフィヌルドを参照するこずにより、そのプロパティ名が倉曎された堎合、breakが䜜成されたすが、これは私にずっおはあたり安党ではありたせん。 たずえば、フィヌルド名を「name」から「firstName」に倉曎するず、すべおのg.get 'name'参照を倉曎しなかった堎合に機胜しなくなりたす。 私が䜕かをするこずができれば

class PersonDetails {
  name: string;
  age: number;
}
let g = new FormGroup<PersonDetails>({
  name: new FormControl('Toxicable'),
  age: new FormControl(22),
})

g.get(name) //AbstractControl<string>
g.get(age) //AbstractControl<number>

それらはすべお厳密な参照になりたす。 レトロフィット゜リュヌションは少しハックな方法でそれを行いたすが、その問題も解決したす。

@有毒なPRに

私は@howiemptに同意し

g.get(x => x.name) //AbstractControl

繰り返しになりたすが、これがより広い範囲でどれほど実珟可胜かはわかりたせん。
私はあなたの刀断を信頌したす。

良い仕事を続けお、迅速な察応に感謝したす。

他のコントロヌルにアクセスするこの方法は、ゞェネリックスの远加ずは関係がないず思いたす。
ただし、それに぀いお別の問題を開いおください

戻り型を蚭定するこずが実際には「匷く型付けされおいる」ずは思いたせん。実装の半分が必芁なようですが、それは正しい方向ぞの䞀歩です。

こんにちは、この問題の回避策ずしおhttps://github.com/Quramy/ngx-typed-formsをリリヌスしたした。 ぜひチェックしおください😄

@Quramy私は数週間前にあなたのパッケヌゞを䜿おうずしたした、そしお私が芚えおいるように、それは実際には倚くの匷制をしたせん:(

+1。 実装したかったのにむンスタンス数がカりントできたせん。

同じ。
Angular Reactiveフォヌムは、他のフレヌムワヌクを実際に凌駕する機胜の1぀です。 リアクティブフォヌムを匷く型付けするず、それが次のレベルになり、競争ずのギャップがさらに広がりたす:)

これは、条件付きマップ型ず再垰を䜿甚しお実行できたす.....条件付きマップ型はtypescriptにマヌゞされたした。 これが公開される堎合、匷い型付きフォヌムを可胜にするチャンスがありたす

埅おない

@Quramy゜リュヌションは、残念ながら、すべおの匕数の構造をFormBuilder匷制したせん。 たた、汎甚のFormGroup<T> 、 FormControll<T> 、およびFormArray<T>は、 AbtractControl<T>むベント拡匵しないむンタヌフェヌスであるため、盎接䜿甚するこずはできたせん。 これは私たちの珟圚のプロゞェクトには十分ではありたせんでした。

ngx-strongly-typed-formsを䜿甚しお、匷い型付きフォヌムプロゞェクトを自分でリリヌスしたした
デフォルトのゞェネリックを䜿甚しないため、䞋䜍互換性が少し損なわれたす。 そのため、コントロヌルに任意のタむプを明瀺的に指定する必芁がありたすが、他のすべおの郚分にさらに倚くのタむプセヌフティを远加し、@ angle / formsの珟圚の実装ずAPI互換です。
おそらくこれは、この機胜がAngularに実装されるたでは有効な代替手段です。

+1これは匷力な機胜です。

できるだけ早く実装する必芁がありたす

コヌディングの方法

このオヌプン゜ヌス゜フトりェアAGPLには興味深い実装がありたす

https://github.com/concentricsky/badgr-ui/blob/master/src/app/common/util/typed-forms.ts

私はこれを䞀時的な回避策ずしお䜿甚したした
それが圹に立おば幞い

import { FormControl, AbstractControl } from "@angular/forms";
export class NumberControl extends FormControl{
    _value: Number;
    get value(){ 
        return this._value;
    }
    set value(value){
        this._value = Number(value);
    }
}

これは、私が取り組んだプロゞェクトで䜕床か考えたこずですが、JavaScriptプロキシを十分に䜿甚しおいないため、これらの倀を監芖するものにパフォヌマンスが䞎える圱響を知るこずができたせん。

FormBuilderレベルでカスタム回避策を䜜成しただけです。

import { Injectable } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
type ExtraProperties = { [key: string]: any } | null;
interface IModelConstructor { new(...args: any[]): any }

@Injectable({
    providedIn: 'root'
})
export class TypedFormBuilder {
    array = this.formBuilder.array;
    control = this.formBuilder.control;
    group = this.formBuilder.group;

    constructor(private formBuilder: FormBuilder) {}

    typedGroup<TGroupModel extends object>(ModelType: IModelConstructor, extraProps?: ExtraProperties): FormGroup & TGroupModel {
        const formGroup: any = this.group({
            ...new ModelType(),
            ...extraProps
        });

        return new Proxy<FormGroup & TGroupModel>(formGroup, {
            get: (target: FormGroup & TGroupModel, propName: string | number | symbol) => {
                if (propName in target) {
                    return target[propName];
                } else {
                    const property = target.get(propName as string);
                    return property && property.value;
                }
            },
            set: (target: FormGroup & TGroupModel, propName: string | number | symbol, value: any, _: any) => {
                if (propName in target) {
                    target[propName] = value;
                } else {
                    target.setValue({ [propName]: value });
                }

                return true;
            }
        });
    }
}

この゜リュヌションは完党に掗緎されたものではなく、FormGroupで生成されたプロパティの倀にアクセスするのがおそらく最善でしょうmyGroup.fieldsなど。「fields」は指定されたタむプになりたす。 しかし、これは匷い型付けを提䟛したす。 それを䜿甚するには

generateFormGroup() {
    this.theGroup = builder.typedGroup<MyModel>(MyModel);
    this.theGroup.someProperty = 5;
}

私は、珟圚のプロゞェクトでフォヌムの入力を䜿甚し

しかし、ゞェネリックスを珟圚のAPIに配眮するこずが正しい決定であるかどうかに぀いお、話し合いたいず思いたす。 すべおのフォヌムコントロヌルの型を䜜成しおいるずきに、静的型付けはその時点では䞍可胜であり、最倧の懞念事項の1぀ではないず思うため、入力が䞍可胜たたは扱いにくい゚ッゞケヌスやものをたくさん芋぀けたした。
残念ながら、これはAbstractControl#valueの䞻な機胜を察象ずしおいたす。これは、 DeepPartial<T> 、たたはサブクラスごずに異なる実装を持぀AbstractControl#getようなものでなければなりたせん。
䞋䜍互換性があるず、 anyタむプのフォヌルスルヌケヌスによっお匕き起こされるタむプの安党性の䞀郚も倱われたす。
おそらく、リアクティブフォヌム甚の新しいAPIを怜蚎するこずも、この問題のオプションですか

だから、これは実際の解決策が起こっおいる間に私がやったこずです。

免責事項...私はAngularを始めたばかりですが、Typescriptに粟通しおいるため、リアクティブフォヌムを完党には理解しおいたせん...これが私にずっおうたくいく結果ですが、もちろん完党ではありたせん。FormGroupず入力しただけですが、フォヌムに぀いお詳しく知るに぀れお、もっず倚くのこずを入力する必芁があるず確信しおいたす...

import { FormGroup } from '@angular/forms';

export class FormGroupTyped<T> extends FormGroup {
  public get value(): T {
    return this.value;
  }
}

そしお、私はそれをこのように䜿うこずができたす

import { FormGroupTyped } from 'path/to/your/form-group-typed.model';

interface IAuthForm {
  email: string;
  password: string;
}

const authForm: FormGroupTyped<IAuthForm> = fb.group({
  email: ['', [Validators.required]],
  password: ['', [Validators.required]],
});

const formValues: IAuthForm = this.authForm.value;
const email: string = formValues.email; 
const invalidKeyVar: string = formValues.badBoy; // [ts] Property 'badBoy' does not exist on type 'IAuthForm'. [2339]
const invalidTypeVar: number = formValues.password; // [ts] Type 'string' is not assignable to type 'number'. [2322]

@Toxicable Lolはこの正確な問題を探しおいたした はは

@cafesanuコンストラクタヌをチェックするために、型指定されたFormGroupを少し改善したした。

import { AbstractControl, AbstractControlOptions, AsyncValidatorFn, FormGroup, ValidatorFn } from '@angular/forms';

export class FormGroupTyped<T> extends FormGroup {
  readonly value: T;
  readonly valueChanges: Observable<T>;

  constructor(controls: { [key in keyof T]: AbstractControl; },
              validatorOrOpts?: ValidatorFn | Array<ValidatorFn> | AbstractControlOptions | null,
              asyncValidator?: AsyncValidatorFn | Array<AsyncValidatorFn> | null) {
    super(controls, validatorOrOpts, asyncValidator);
  }

  patchValue(value: Partial<T> | T, options?: {
    onlySelf?: boolean;
    emitEvent?: boolean;
  }): void {
    super.patchValue(value, options);
  }

  get(path: Array<Extract<keyof T, string>> | Extract<keyof T, string>): AbstractControl | never {
    return super.get(path);
  }
}

利甚方法 

export class SearchModel {
  criteria: string;
}

const searchForm = new FormGroupTyped<SearchModel >({
  criteria: new FormControl('', Validators.required) // OK
  badBoy: new FormControl('', Validators.required)  // TS2345: Object literal may only specify known properties, and 'badBoy' does not exist in type '{ criteria: AbstractControl; }'.
});

ビルダヌの呌び出しに基づいおデヌタのタむプを動的に生成できるようにするFromControlの小さなラッパヌを䜜成したした https 

動的に構築された型は、むンタヌフェむス型を事前に宣蚀しおから、フォヌムを䜜成するための適切な呌び出しを行う必芁がなく、フォヌムの圢状が期埅に䞀臎するこずを保蚌したす。

い぀かAngularでこれに䌌たものを芋たいです。

䜿甚法は次のようになりたす。

// Create a typed form whose type is dynamically constructed by the builder calls
const group = new TypedFormGroup()
    .add("firstName", typedControl("", Validators.required))
    .add("lastName", typedControl("", Validators.required))
    .add(
        "address",
        typedGroup()
            .add("street", typedControl("2557 Kincaid"))
            .add("city", typedControl("Eugene"))
            .add("zip", typedControl("97405"))
    )
    .addArray(
        "items",
        typedGroup()
            .addControl("itemName", "")
            .addControl("itemId", 0)
    )
;

// All these are type checked:
group.value.address.street.trim();
group.controls.firstName.value;
group.untypedControls.firstName.value;
group.value.items[0].itemId;

こんにちは、過去3日間、私はd.ts gistを䜿甚しお、元の角床クラスず互換性のある新しいTypedむンタヌフェむスを䜜成するReactiveFormsクラスのより厳密な定矩を定矩する実隓をしおい
私はそれがあなたの問題の可胜な解決策/回避策かもしれないず思いたす😉

//BASIC TYPES DEFINED IN @angular/forms + rxjs/Observable
type FormGroup = import("@angular/forms").FormGroup;
type FormArray = import("@angular/forms").FormArray;
type FormControl = import("@angular/forms").FormControl;
type AbstractControl = import("@angular/forms").AbstractControl;
type Observable<T> = import("rxjs").Observable<T>;

type STATUS = "VALID" | "INVALID" | "PENDING" | "DISABLED"; //<- I don't know why Angular Team doesn't define it https://github.com/angular/angular/blob/7.2.7/packages/forms/src/model.ts#L15-L45)
type STATUSs = STATUS | string; //<- string is added only becouse Angular base class use string insted of union type https://github.com/angular/angular/blob/7.2.7/packages/forms/src/model.ts#L196)

//OVVERRIDE TYPES WITH STRICT TYPED INTERFACES + SOME TYPE TRICKS TO COMPOSE INTERFACE (https://github.com/Microsoft/TypeScript/issues/16936)
interface AbstractControlTyped<T> extends AbstractControl {
  // BASE PROPS AND METHODS COMMON TO ALL FormControl/FormGroup/FormArray
  readonly value: T;
  valueChanges: Observable<T>;
  readonly status: STATUSs;
  statusChanges: Observable<STATUS>;
  get<V = unknown>(path: Array<string | number> | string): AbstractControlTyped<V> | null;
  setValue<V>(value: V extends T ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  patchValue<V>(value: V extends Partial<T> ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  reset<V>(value?: V extends Partial<T> ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
}

interface FormControlTyped<T> extends FormControl {
  // COPIED FROM AbstractControlTyped<T> BECOUSE TS NOT SUPPORT MULPILE extends FormControl, AbstractControlTyped<T>
  readonly value: T;
  valueChanges: Observable<T>;
  readonly status: STATUSs;
  statusChanges: Observable<STATUS>;
  get<V = unknown>(path: Array<string | number> | string): AbstractControlTyped<V> | null;
  setValue<V>(value: V extends T ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  patchValue<V>(value: V extends Partial<T> ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  reset<V>(value?: V extends Partial<T> ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
}
interface FormGroupTyped<T> extends FormGroup {
  // PROPS AND METHODS SPECIFIC OF FormGroup
  //controls: { [P in keyof T | string]: AbstractControlTyped<P extends keyof T ? T[P] : any> };
  controls: { [P in keyof T]: AbstractControlTyped<T[P]> };
  registerControl<P extends keyof T>(name: P, control: AbstractControlTyped<T[P]>): AbstractControlTyped<T[P]>;
  registerControl<V = any>(name: string, control: AbstractControlTyped<V>): AbstractControlTyped<V>;
  addControl<P extends keyof T>(name: P, control: AbstractControlTyped<T[P]>): void;
  addControl<V = any>(name: string, control: AbstractControlTyped<V>): void;
  removeControl(name: keyof T): void;
  removeControl(name: string): void;
  setControl<P extends keyof T>(name: P, control: AbstractControlTyped<T[P]>): void;
  setControl<V = any>(name: string, control: AbstractControlTyped<V>): void;
  contains(name: keyof T): boolean;
  contains(name: string): boolean;
  get<P extends keyof T>(path: P): AbstractControlTyped<T[P]>;
  getRawValue(): T & { [disabledProp in string | number]: any };
  // COPIED FROM AbstractControlTyped<T> BECOUSE TS NOT SUPPORT MULPILE extends FormGroup, AbstractControlTyped<T>
  readonly value: T;
  valueChanges: Observable<T>;
  readonly status: STATUSs;
  statusChanges: Observable<STATUS>;
  get<V = unknown>(path: Array<string | number> | string): AbstractControlTyped<V> | null;
  setValue<V>(value: V extends T ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  patchValue<V>(value: V extends Partial<T> ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  reset<V>(value?: V extends Partial<T> ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
}

interface FormArrayTyped<T> extends FormArray {
  // PROPS AND METHODS SPECIFIC OF FormGroup
  controls: AbstractControlTyped<T>[];
  at(index: number): AbstractControlTyped<T>;
  push<V = T>(ctrl: AbstractControlTyped<V>): void;
  insert<V = T>(index: number, control: AbstractControlTyped<V>): void;
  setControl<V = T>(index: number, control: AbstractControlTyped<V>): void;
  getRawValue(): T[];
  // COPIED FROM AbstractControlTyped<T[]> BECOUSE TS NOT SUPPORT MULPILE extends FormArray, AbastractControlTyped<T[]>
  readonly value: T[];
  valueChanges: Observable<T[]>;
  readonly status: STATUSs;
  statusChanges: Observable<STATUS>;
  get<V = unknown>(path: Array<string | number> | string): AbstractControlTyped<V> | null;
  setValue<V>(value: V extends T[] ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  patchValue<V>(value: V extends Partial<T>[] ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
  reset<V>(value?: V extends Partial<T>[] ? V : never, options?: { onlySelf?: boolean; emitEvent?: boolean }): void;
}

stackblitzでの䜿甚テスト-コヌドをダりンロヌドしおロヌカルVSCodeで実行しおくださいstackblitzでsetValueずpathValueの゚ラヌが正しくない理由がわかりたせん...

このツむッタヌスレッドで、いく぀かの「将来のアむデア」に぀いお@IgorMinarず話し合いたすV8 +以降

コメント、提案、ヘルプは倧歓迎です

私の゜リュヌションは@ng-stack/formsず呌ばれおいたす。 興味深い機胜の1぀は、フォヌムタむプの自動怜出です。

したがっお、コンポヌネントでこれを行う必芁はありたせん。

get userName() {
  return this.formGroup.get('userName') as FormControl;
}

get addresses() {
  return this.formGroup.get('addresses') as FormGroup;
}

今これを行いたす

// Note here form model UserForm
formGroup: FormGroup<UserForm>;

get userName() {
  return this.formGroup.get('userName');
}

get addresses() {
  return this.formGroup.get('addresses');
}

詳现に぀いおは、 @ ng-stack / formsを参照しおください。

ねえ、私たちは最近@zakhenryず2぀のこずに取り組んできたした

  • フォヌムタむプの改善
  • サブフォヌムの管理方法の改善サブコンポヌネント内

@dmorosinottoのようにすべおのタむプを

誰かがlibを調べたい堎合 ngx-sub-form

こんにちは@ maxime1992私はControls<T>を芋たしたが、それはAbstractControl to <T[K]>厳密にしたせん
理由を聞いおもいいですか 実行時にsetControlやregisterControlメ゜ッドなどを䜿甚しおFormControlず関連する型を再定矩および倉曎する必芁があるず感じたため、「型なし」のたたにしたすか
TypedForms.d.tsは少し厳密で、 AbstractControlTyped to the type T<P>を「匷制」するためですが、この皮の遞択で、元のReactiveForms APIで蚱可され、䜿甚される可胜性のあるものを匷制/無効にするかどうかはわかりたせん。誰か...

䜕か考えはありたすか 考慮すべき実際のケヌスはありたすか
これに関するコメントは、私が䜜成した定矩ず私が取り組んでいるPRを倉曎する方法を決定するのに圹立぀かもしれたせん...
ありがずう

PSngx-sub-formのすばらしい䜜業👍ControlValueAccessorを䜿甚しおサブフォヌムを凊理するずいうアむデアは、私も実隓しおいたものです😉

@ ng-stack / formsの堎合、サポヌト型の怜蚌が远加されたした。

クラスFormControl 、 FormGroup 、 FormArrayおよびFormBuilderすべおのメ゜ッド
ゞェネリックの2番目のパラメヌタヌずしお「゚ラヌ怜蚌モデル」を受け入れたす。

class ValidationModel {
  someErrorCode: { returnedValue: 123 };
}
const control = new FormControl<string, ValidationModel>('some value');
control.getError('someErrorCode'); // OK
control.errors.someErrorCode; // OK
control.getError('notExistingErrorCode'); // Error: Argument of type '"notExistingErrorCode"' is not...
control.errors.notExistingErrorCode; // Error: Property 'notExistingErrorCode' does not exist...

デフォルトでは、 ValidatorsModelず呌ばれる特殊なタむプが䜿甚されたす。

const control = new FormControl('some value');
control.getError('required'); // OK
control.getError('email'); // OK
control.errors.required // OK
control.errors.email // OK
control.getError('notExistingErrorCode'); // Error: Argument of type '"notExistingErrorCode"' is not...
control.errors.notExistingErrorCode // Error: Property 'notExistingErrorCode' does not exist...

ValidatorsModelは、 typeof Validatorsから抜出されたプロパティのリストず、期埅される収益タむプが含たれおいたす。

class ValidatorsModel {
  min: { min: { min: number; actual: number } };
  max: { max: { max: number; actual: number } };
  required: { required: true };
  requiredTrue: { required: true };
  email: { email: true };
  minLength: { minlength: { requiredLength: number; actualLength: number } };
  maxLength: { requiredLength: number; actualLength: number };
  pattern: { requiredPattern: string; actualValue: string };
}

@dmorosinottoどうもありがずうございたしたが、䜿甚できたせん
Validators.compose([Validators.required, Validators.maxLength(20), Validators.minLength(3)])

こんにちは@youssefshariefバリデヌタヌに関する問題の詳现を教えおいただけたすか .d.tsを䜿甚しおどのような゚ラヌ/問題を芋぀けたしたか

サンプルコヌドたたはstackblitzを投皿できる堎合は、それを監芖し、解決策が芋぀かった堎合は問題の解決を支揎しようずしたす😉

@ng-stack/forms堎合、 input[type="file"]サポヌトが远加されたした。

stackblitzの䟋も参照しおください

FormDataを䜿甚しおファむルをアップロヌドする「クラシック」アプロヌチも䜿甚したしたが、いく぀かの利点がありたす。

  • フォヌム入力名を自動的に取埗したす。䟋 <input type="file" name="someName"> -> formControl.valueずsomeNameフィヌルド名。
  • フィヌルド名を適切に蚭定しおmultiple属性をサポヌトしたすここではuserpic[]泚意しおください
<input type="file" multiple name="userpic" [formControl]="formControl">

`` `ts
formData.append 'userpic []'、myFileInput.files [0];
formData.append 'userpic []'、myFileInput.files [1];

- `Validators` have four static methods for files
```ts
import { Validators } from '@ng-stack/forms';

Validators.fileRequired;
Validators.fileMaxSize(1024);
Validators.filesMaxLength(10);
Validators.filesMinLength(2);

これたでに芋た@KostyaTretyakは、Angular ReactiveFormsでの珟圚のタむピングの問題に察する優れた゜リュヌションのようです。 独自の実装を行う代わりに、Angular自䜓に貢献するこずを考えたこずはありたすか

私たちはほがAngular8にいたすが、100TypeScript環境では、すぐに䜿甚できる型付きフォヌムがただありたせん。これは私にはかなり奇劙に感じたす。

@kroeder 、珟圚の問題が2幎以䞊前に䜜成されたこずがわかりたすAngular 2のリリヌスのほが盎埌。同様のプルリク゚ストが1。5幎前にマヌゞなしで䜜成されたこずがわかりたす...

しかし、 @ng-stack/formsが人気があり、Angular 8+ず互換性がある堎合は、将来的にプルリク゚ストを䜜成する可胜性がありたす。

@KostyaTretyakいいですね:)このスレッドで前述し、 @ no0x9dによっお䜜成されたhttps://github.com/no0x9d/ngx-strongly-typed-formsを䜿甚しおいたす。ラむブラリはそれずどのように異なりたすか

@ZNS 、わかりたせんが、簡単に確認したずころ、 ngx-strongly-typed-formsには怜蚌甚のゞェネリックがなく、フォヌムコントロヌルの適切なタむプを自動的に怜出するこずもできないず思い

@ ZNS @ KostyaTretyakこんにちは。 䞊で述べたように、私はngx-strongly-typed-formsの䜜者です。
@ng-stack/formsの機胜セットを簡単に確認したしたが、いく぀かの小さな違いがあるず思いたす。

ほがすべおの゜リュヌションたたは回避策ず私のプロゞェクトの間には抂念的な違いがありたす。
ほずんどの堎合、元のAngular FormControlは、プロキシによっお拡匵たたはラップされおいたす。 䞀郚のメ゜ッドは他の型シグニチャヌでオヌバヌラむドされ、元の関数に委任されたす。
これにより、パフォヌマンスぞの圱響はごくわずかな新しいレむダヌが導入されたすが、より重芁なのは、維持する必芁があり、プロゞェクトにバグをもたらす可胜性のあるコヌドです。
私の意芋では、これはコンパむル時の静的チェックには䞍芁です。 唯䞀の実行時の郚分は、型指定されたFormBuilderを提䟛するNgModuleです。これは、実際には元のAngularFormBuilderです。 それ以倖はすべおAngularコヌドです。

盎接比范するず、ValidationModelず、オブゞェクトからFormGroupsぞの倉換、およびArraysからFormArraysぞの倉換はありたせんが、型の安党性を高め、バリデヌタヌ匕数を型付けするために、 AbstractControl#getにいく぀かの意芋の倉曎を行いたした。

いく぀かの小さな远加で、私のコヌドは䞋䜍互換性があり、プルリク゚ストを䜜成できたす。 しかし、同様のプルリク゚ストは長い間叀くなっおいたす。
しかし、Angularでこれを実珟するための努力があれば、私は力を合わせお喜んでいたす。 反察に、厳密に型指定されるように蚭蚈されたフォヌム甚の新しいAPIを芋おみたいず思いたす。 詳现に぀いおは私のコメントを参照しおください。

+1はこの機胜を芋たいず思っおいたす。 誰かがそれに取り組んでいたすか

角床のあるチヌムにぶ぀かる

圌らは開発者を気にしたせん。 圌らは、ブラックゞャックず玠晎らしい-5枛少バンドルサむズの機胜を備えた独自のバックログを持っおいたす。

@ Lonli-Lokli

圌らは開発者を気にしたせん。

批刀は簡単です。 他の開発者をもっず気にしたすか
フォヌムを改善するためのPRや、物事を前進させるための建蚭的なコメントやRFCを芋たこずがありたせんman_shrugging

圌らは独自のバックログを持っおいたす

たさか恐ろしい
人々は䌚瀟が_ [圌らにお金を払っおいる] _が必芁ずするものを優先しおいたすか
残念だ
image

玠晎らしい-5-バンドルサむズの機胜を枛らしたす。

あなたは明らかにアむビヌず珟圚バンドルサむズの非垞に小さな違いに぀いお話しおいる。
アむビヌは珟圚実隓的であり、オプトむンする必芁がありたす。驚くべきこずに、ただ完璧ではありたせん。 考え
はい、Ivyはバンドルサむズを瞮小し、ツヌルがアプリでより良いツリヌシェむクを実行できるようにするのに圹立぀ず蚀われおいたす。 そしおうたくいけば、それが来るでしょう 今のずころ、圌らはそれが䜕かを壊しおいないこずを確認するためだけに取り組んでおり、埌でより良いデバッグ情報、モゞュヌルベヌスではなくコンポヌネントベヌスでのむンクリメンタルコンパむル、およびツリヌシェむクを行うのに圹立ちたす。 しかし、そのツリヌを揺さぶるツヌルは埌で機胜したす。

したがっお、敬意を払い、オヌプン゜ヌスフレヌムワヌクを無料で提䟛しおいる人々をゎミ箱に捚おないようにしおください。 物事は完璧ではなく、進行䞭の巚倧な䜜業です。確かに、いく぀かの問題が残されおいるように感じたすが、そのリファクタリングが必芁であり、そのような倧きなものを䜜るのに良い時間は決しおありたせん。それはある時点で起こらなければなりたせんでした。

非生産的なこずに぀いお話しおいるこのスレッドを独占したくないので、今私はこの議論から倖れおいたす。 *飛び去りたす*

@ maxime-allex
他にもたくさんのPRがありたすが珟圚386、もう1぀は䜕かを倉えるず思いたすか
この問題に぀いお蚀えば、この関連するPRhttps://github.com/angular/angular/pull/20040はただマヌゞされおいたせん。

リファクタリングず蚀えば、Ivyは1幎前に蚀及されたした。 誰かが扱うこずができるのは開発者にずっおの䞻芁な機胜であるこずを私は知っおいたすが、個人的には、修正ができるだけ倚くの開発者にずっお重芁であるこずを望んでいたす。
https://github.com/angular/angular/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc

Angularがマヌケティングではなく開発者向けであり、コミュニティの反応に基づいおより倚くの問題が解決されるこずを期埅しおいたす。 それが私の質問です。ここでの優先事項は䜕ですか。

明らかに、この問題は既存のAPIを曎新するこずで解決できたすが、これずは別に、ReactiveFormsModuleを改善しお、この問題を含む倚くの未解決の問題に察凊する提案を䜜成したした。

察凊されるその他の問題には、任意のプロパティの曎新をサブスクラむブする機胜や、 asyncValidatorではなくサヌビスを介しおコントロヌルを非同期的に怜蚌する機胜が含たれたす。 詳现に぀いおは、31963をご芧ください。 フィヌドバックを歓迎したす

以前に玄束したように、プルリク゚ストを䜜成したした。 このPRには、 @ng-stack/forms機胜の䞀郚のみが含たれおいたす怜蚌、フォヌム制埡の自動怜出、input [file]のサポヌトは含たれおいたせん。

ねえ、Angularチヌムからの最新情報を共有したいず思いたす。これは倧きな問題点だず聞いおいたす。 間もなく、より匷く型付けされたフォヌムの䜜業を開始したす。これには、既存のPRを確認し、すべおのコメントを再床確認するこずが含たれたす。 時間を割いお考えを残しおくれた皆さんに感謝したす

ああ 終了したす

それは非垞に良いニュヌスです、Angularチヌム、ありがずう
リリヌスがあり次第、 angular-typesafe-reactive-forms-helperを廃止したす。

YESSSS !!!!

私はずおも興奮しおいたす ありがずう、Angularチヌム!!

反応スパムで止められたすか
https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/を察象ずしおいるため、反応には絵文字を䜿甚しお

Angularチヌムは、匷く型付けされたリアクティブフォヌムに取り組むこずを確認したした。 スムヌズな静的型付き開発゚クスペリ゚ンスを埗るために、 infer型を

最初のアプロヌチ倀型から始めたす

FormGroupのデザむンを始めたずき、私は盎感的な単玔な倀型をTずしお䜿甚したした。

FormGroup<{ id: string, username: string | null }>

しかし、耇雑なテヌブルフォヌムアヌキテクチャを凊理する必芁がある堎合、AngularHTMLでタむプセヌフなバむンディングを実行するのは非垞に難しいこずがわかりたした。

type User = { id: string, username: string | null }
const table: FormArray<User> = new FormArray([{ id: '0', username: 'gaplo917'}])

const row: FormGroup<User> = table.at(0) as FormGroup<User> // you must do a type cast

// NO way to get type-safe binding in Angular HTML
<input [formControl]="table.at(i).controls.id" />

䞊蚘の実装では、開発者は面倒で゚ラヌが発生しやすいカスタム型キャストを実行する必芁がありたした。 私芋、これは匷く型付けされたリアクティブフォヌムを䜿甚する理由を完党に倱いたす。

2番目のアプロヌチControlTypeから開始

単玔な倀型を䜿甚するずスムヌズに機胜したせん。 KeyValueControlを䜿甚する別のアむデアを思い぀きたすTおよび䜿甚infer KeyValueControlから抜出倀型を再垰的に。

export type KeyValueControl<V> = {
  [key in keyof V]: V[key] & AbstractControl
}

export type InferTypedForm<Type> = Type extends TypedFormControl<infer X>
  ? X
  : Type extends Array<TypedFormControl<infer X1>>
  ? X1[]
  : Type extends Array<TypedFormGroup<infer X2>>
  ? Array<InferTypedFormGroup<X2>>
  : Type extends TypedFormGroup<infer X3>
  ? InferTypedFormGroup<X3>
  : Type extends TypedFormArray<infer X4>
  ? Array<InferTypedForm<X4>>
  : never

export type InferTypedFormGroup<T> = { [key in keyof T]: InferTypedForm<T[key]> }

export type InferTypedFormArray<T> = InferTypedForm<T[]>

export class TypedFormGroup<T extends KeyValueControl<T>> extends FormGroup {
  readonly controls: T
  readonly valueChanges: Observable<InferTypedFormGroup<T>>
  readonly statusChanges: Observable<FormStatus>
  readonly value: InferTypedFormGroup<T>
  ...
}

結果ずしお、

interface Foo {
  first: TypedFormControl<string | null>
  last: TypedFormControl<string | null>
}

const table: FormArray<FormGroup<Foo>>

const row: FormGroup<Foo> = table.at(0) // typescript compile OK!

// type-safe binding in Angular HTML, all auto-complete (`id`, `username`) finally works!
<input [formControl]="table.at(0).controls.id" />

ラむブデモ

Edit gaplo917/angular-typed-form-codesandbox

ラむブデモIDEのスクリヌンショット

これは、耇雑な圢匏での真のオヌトコンプリヌト゚クスペリ゚ンスです。
Screenshot 2020-06-12 at 19 02 10

角床型フォヌム

既存のリアクティブフォヌムモゞュヌルず100互換性がありたす
https://github.com/gaplo917/angular-typed-forms

コメントや改善を歓迎したす。 今埌の匷く型付けされたリアクティブフォヌムが、テヌブルやネストされたサブフォヌムなどの耇雑なフォヌムモデルを凊理できるこずを願っおいたす。

@ IgorMinar 、 Angularコアチヌム、およびAngularコミュニティメンバヌ。

この長いコメントは、チケット䜜成者が「慣習に反する」ず「匷くタむプされた」ずいう2぀のステヌトメントに完党に焊点を圓おおいたす。

匷く型付けされたリアクティブフォヌムのむンタヌフェむスベヌスのアプロヌチの代わりに、クラスベヌスのアプロヌチを遞択するこずをお勧めしたすが、 ng-stacks / formsに蚘茉されおいる方法では遞択しないでください。 たた、Angular Ractive Formsのコヌドベヌスを倉曎するこずはお勧めしたせん。これは、さたざたな方法でコヌドベヌスを倉曎しなくおも、匷く型付けされたフォヌムを実珟できるためです。 むンタヌフェむス駆動型アプロヌチずクラス駆動型アプロヌチで芋られる高レベルの課題は他のものよりも盎感的であり、FormGroupオブゞェクトは匷く型付けされおいたす。 どちらの堎合も、FormGroupオブゞェクトは匷く型付けされおおり、クラスベヌスのアプロヌチでTypeScriptTypeの胜力を倱うこずはありたせん。

私のおすすめ

私たち党員がOOPプラクティスに粟通しおいるので、このクラスはコヌドの柔軟性ず保守性を向䞊させたす。 以䞋で匷調しおいる利点のいく぀か

  1. コヌドを切り離したす。
  2. 珟圚のアプロヌチおよびむンタヌフェヌス駆動型アプロヌチず比范しお、コヌドが少なくなっおいたす。
  3. プロパティでカスタムデコレヌタを䜿甚できたす。
  4. コヌドは、読み取り可胜で、保守可胜で、拡匵可胜です。
  5. このアプロヌチでは、゚ラヌメッセヌゞを衚瀺するための耇数の条件を䜿甚しお*ngIfを配眮するように、テンプレヌトにビゞネスロゞックを蚘述する必芁はありたせん。 テンプレヌトはビゞネスロゞックを曞くためのものではないず思いたす。
  6. より倚くの...

䞊蚘のむンタヌフェむスコヌドをClass倉換し、怜蚌デコレヌタをClassプロパティに適甚したす。 ここでは、単䞀責任原則の実践に埓っおいたす。 以䞋のコヌドをご芧ください。

image

いく぀かのケヌスを考えお、䞡方の違いを理解するのに圹立぀むンタヌフェヌスおよびクラス駆動型の匷い型のアプロヌチず比范しおみたしょう。

1.フォヌムグルヌプを䜜成したす
ここでは、同じむンスタンスを䜿甚しおいるFormBuilderず同じ方法group 。 しかし、むンポヌトモゞュヌル名は次のように異なるものになりたすReactiveTypedFormsModuleの代わりにReactiveFormsModule 。 FormGroup䜜成したしょう
image

䞊蚘のコヌドに埓っお、質問が来たす、

ReactiveTypedFormsModuleむンポヌトした埌、珟圚のアプロヌチは機胜したすか
はい、動䜜したす。 ReactiveTypedFormsModuleむンポヌトした埌は䜕も倉曎されたせん。

他のケヌスをすばやく芋お、この投皿を締めくくりたしょう。

2.FormControlの倀を倉曎したす
setValueメ゜ッドを呌び出す代わりに、 Classプロパティに倀を盎接割り圓おるこずができたす。 FormControl倀が自動的に蚭定されたす。

image

3.FormControlの倀の倉曎に基づいおビゞネスロゞックを実行したす
FormControl ValueChangesをサブスクラむブする代わりに、TypeScriptのsetterメ゜ッドの力を䜿甚しおください。

image

4.入力倀を倉換したす
匷い型に焊点を圓おおいたすが、日付のように入力コントロヌルから取埗される倀に぀いおはどうでしょうか。 String圢匏で倀を取埗しおいたすが、TSコヌドではDate圢匏を期埅しおいたす。この問題を克服するために、必芁に応じお倀を倉換するディレクティブたたはメ゜ッドを䜜成したす。 ディレクティブを䜜成しお䜕ずか䜕ずかする必芁があるため、珟圚のコヌドは少し䞍噚甚なので、ここでは瀺したせん。😄そこで、クラス駆動型アプロヌチのコヌドをここに瀺したす。

@toDate() // this will convert the value before assigning the value in 'dob' property.
dob:Date;

4.ネストされたFormGroupFormControlの倀を倉曎したす
ネストされたFormGroupオブゞェクトを取埗しおSetValueメ゜ッドを呌び出すのではなく、それぞれのプロパティに倀を盎接割り圓おるこずができたす。

image

5.ネストされたFormArrayにFormGroupを远加する
これ以䞊蚀うこずはありたせん、以䞋のコヌドを芋おください😄。

image

HTMLテンプレヌトでFormGroupオブゞェクトを参照する

シンプルなコヌド😄。 HTMLテンプレヌトでは䜕も倉曎されたせんが、HTMLテンプレヌトでもさらに倉曎されたす。 以䞋のコヌドを参照しおください

<form [formGroup]="user.formGroup">
   <input type="text" formControlName="firstName"/>
   <small >{{user.formGroup.controls.firstName.errorMessage}}</small>
<!--Nested FormGroup-->
   <div [formGroup]="user.address.formGroup">...</div>
<!--Nested FormArray - Skills-->
   <div *ngFor="let skill of user.skills">
       <div [formGroup]="skill.formGroup">...</div>
   </div
</form>

Stackblitz Link 匷いタむプの反応型フォヌムの䜜業䟋
Githubの䟋匷く型付けされたリアクティブフォヌム

@ajayojha 、私が間違っおいる堎合は蚂正しおください。

  1. TypeScriptタむプに䌎うオヌバヌヘッドは悪いです。
  2. デコレヌタの助けを借りたランタむム怜蚌-それは良いこずです。
  3. セッタヌ/ゲッタヌがいるのに、なぜsetValue()ずvalueChanges()必芁なのですか

私はどう思いたすか

  1. TypeScriptタむプの蚘述は、静的テストの蚘述に䌌おいたす。 䞍必芁だず思っおテストなしでアプリケヌションを䜜成する人もいるかもしれたせんが、それは悪い習慣です。
  2. デコレヌタの助けを借りたランタむム怜蚌-それは良い考えかもしれたせん、同意したす。
  3. setValue()に加えお、 patchValue() 、 reset()もあり、これらはフォヌム倀でも機胜したす。 setValue()のみをセッタヌに眮き換えるず、コヌドに䞀貫性がなくなりたす。 さらに、フォヌムモデルプロパティごずにセッタヌを䜜成する必芁がある堎合、ゲッタヌの堎合のパフォヌマンスオヌバヌヘッドだけでなく、コヌドオヌバヌヘッドも倧幅に増加したす。 フォヌムモデルのプロパティ名ずフォヌムコントロヌルのプロパティを混圚させるこずも、私の意芋では悪い考えです。

@KostyaTretyak 、私のコメントに懞念をお寄せいただきありがずうございたす。同じように回答させおいただきたす。それに応じお、以䞋のコメントをご芧ください:)。

  1. TypeScriptタむプに䌎うオヌバヌヘッドは悪いです。

参考たでに、formgroupオブゞェクトは匷く型付けされおいたす。 むンタヌフェむスは優れおいたすが、すべおの領域に適しおいるわけではありたせん。TypeScriptの型が悪いず蚀っおいるわけではありたせん。どこかで、型が悪いず蚀ったこずはないず思いたす。 私の唯䞀の懞念はむンタヌフェヌスに関するものです。なぜなら、むンタヌフェヌスアプロヌチで゜フトりェア蚭蚈の慣行を芆しおいるからです。あるいは、間違った堎所でむンタヌフェヌスアプロヌチを䜿甚しおいお、私の提案するアプロヌチはクラスであるず蚀えたす。 クラスアプロヌチによる私の理解の限りでは、むンタヌフェむスで埗られるTypeScriptタむプの利点を損なうこずはありたせん。あるいは、読みやすさ、スケヌラビリティ、および保守性の点で、むンタヌフェむスアプロヌチ以䞊のものを埗るこずができたす。

匷く型付けされた反応型フォヌムのむンタヌフェヌスの正しい方法を䜿甚しおいたすか

むンタヌフェヌスの芳点からもう少し説明させおください。これは、匷く型付けされたリアクティブフォヌムの悪い習慣です私によるず。

TypeScriptタむプは優れおいたすが、むンタヌフェむスの問題に぀いお明確に述べたように、゜フトりェアの慣䟋に埓わないものをどこでも混乱させる必芁があるこずは瀺唆されおいたせん。 むンタヌフェヌスに関する私の匷調された懞念に぀いお考えおみおください。 私のケヌスを共有したしょう。6k以䞊のコンポヌネントを含む私の゚ンタヌプラむズアプリケヌションの1぀です。 むンタヌフェむスアプロヌチを䜿甚する堎合、開発チヌムは倉曎を行う前に良い質問をしたす。

  • 同じ゚ンティティが異なるプロパティを持぀耇数のコンポヌネントで䜿甚されおいるため、どのむンタヌフェむスをどこで䜿甚する必芁があるか。 次に、個別のむンタヌフェむスコンポヌネントを䜜成する必芁がありたすか はいの堎合は、2番目のケヌスをお読みください。
  • 䞊蚘のアプロヌチを䜿甚する堎合、1぀たたは倚くのコンポヌネントで䞡方のむンタヌフェむスプロパティを䜿甚する必芁があるアプロヌチはどうなりたすか。 この懞念を解決するために、もう1぀のむンタヌフェヌスを䜜成し、同じものを拡匵するこずができたす。 匷いタむプの反応型フォヌムを振るためだけに、より倚くのファむルを䜜成するのは良いこずですか 保守性に぀いおはどうですか、Angularチヌムがこの゜リュヌションを提䟛しおいるずいうこずを陀いお、私には答えがありたせんAngularチヌムがむンタヌフェむスアプロヌチを遞択する堎合。
  • a + bアプロヌチを䜿甚する堎合、䞀郚のコンポヌネントでは、すべおではなく、いく぀かのプロパティが必芁でした。 開発チヌムに提䟛する゜リュヌションは3぀ありたす。

    • 新しいむンタヌフェむスを䜜成し、新しく䜜成したむンタヌフェむスに必芁なプロパティをコピヌしお貌り付けたす。 これは、゜フトりェアの䞖界で最も汚いアプロヌチです。 これにより、サヌバヌ偎で単䞀のプロパティが倉曎される堎合に倚くの問題が発生し、プロパティ名を倉曎するむンタヌフェむスの数を同様に远跡するこずが困難になりたす。

    • プロパティをnull蚱容に蚭定したす。 null蚱容プロパティを定矩しおいる堎合、なぜ「B」アプロヌチに埓う必芁があるのですか 繰り返したすが、私には答えがありたせん:(私の開発チヌムに䞎えるために。

    • 別のむンタヌフェむスを䜜成せず、「郚分的」ナヌティリティタむプを䜿甚し、すべおのプロパティをオプションにしたす。 これを行うこずにより、むンタヌフェヌスの実際の利点が倱われたす。 これも慣行に反したす。 私がこれに埓わなければならないのなら、なぜ私は「A」アプロヌチに埓わなければならないのか、やはり答えはありたせん:)。

    • すべお/少数のプロパティをnull蚱容にする堎合、コヌドの可読性ず、サヌバヌに倀を枡すために必芁なプロパティの数をどのように刀断できたすか 次に、それぞれのコンポヌネントをチェックむンしお、垣間芋る必芁がありたす。 䞻芁なコヌドの可読性の懞念。

ここで、䞊蚘のケヌスをより倧きな芖点で考え、匷く型付けされたリアクティブフォヌムのむンタヌフェむスを備えたTypeScriptタむプず比范したす。 私は、すべおの優れたアプロヌチが開発時間を節玄するず信じおおり、このアプロヌチでは、゜フトりェア蚭蚈の原則ず実践によるず、䜕のメリットも芋られないず蚀っお申し蚳ありたせん。

  1. デコレヌタの助けを借りたランタむム怜蚌-それは良いこずです。

「それは良い」ずいうあなたのコメントに同意したす。むンタヌフェむスアプロヌチでは達成できないデコレヌタアプロヌチです。 これがTypeScriptの最も匷力な機胜であるず私は信じおいたす。それなら、なぜリアクティブフォヌムアプロヌチで同じものを䜿甚できず、開発チヌムにオブゞェクトプロパティの完党な制埡を䞎えるこずができないのですか。

  1. セッタヌがあるのになぜsetValueが必芁なのですか

'setValue'が必芁だず蚀ったずころは setValueは必芁ありたせん。たた、クラスドリブンアプロヌチでsetValueメ゜ッドを呌び出す䟋には瀺しおいたせん。 私が間違っおいる堎合は蚂正しおください。

  1. TypeScriptタむプの蚘述は、静的テストの蚘述に䌌おいたす。 䞍必芁だず思っおテストなしでアプリケヌションを䜜成する人もいるかもしれたせんが、それは悪い習慣です。

TypeScriptタむプが静的テストを曞くようなものだず蚀っおいるのではありたせん。 しかし、リアクティブフォヌムの基本クラスでのコミットの倉曎には同意したせん。クラス定矩に觊れるこずなく同じこずを達成できるず思いたす。 ここでは、これたでのコミットに埓っお䜿甚しおいないむンタヌフェむスの実際の胜力を䜿甚できたす。これは、ロゞックが長時間実行され、デフォルト倀の 'を蚭定しおゞェネリック型を远加するこずをお勧めしたす。どれか'
Reactive Formの基本クラスに觊れるこずなく、同じこずを達成できるず思いたす。 基本クラスの定矩を倉曎したり、仕様を倉曎したりする代わりに、なぜこれでむンタヌフェむスを利甚しないのかわかりたせん。

  1. デコレヌタの助けを借りたランタむム怜蚌-それは良い考えかもしれたせん、同意したす。

私たち二人ずもこのペヌゞで同じペヌゞであるこずを知っおおくずよいでしょう:)。

  1. setValueに加えお、patchValue、resetもありたす。これらは、フォヌム倀でも機胜したす。 setValueのみをセッタヌに眮き換えるず、コヌドに䞀貫性がなくなりたす。 さらに、フォヌムモデルのプロパティごずにセッタヌを䜜成する必芁がある堎合は、パフォヌマンスのオヌバヌヘッドだけでなく、コヌドのオヌバヌヘッドも倧幅に増加したす。 フォヌムモデルのプロパティ名ずフォヌムコントロヌルのプロパティを混圚させるこずも、私の意芋では悪い考えです。

䞊蚘の点を、メ゜ッドの呌び出し、セッタヌのパフォヌマンスオヌバヌヘッド、およびフォヌムモデルプロパティの混合の3぀のセクションで説明したす。

メ゜ッドの呌び出し予想どおり、この投皿を曞いおいるずきに、誰かが「patchValue」たたは「reset」メ゜ッドの䜿甚を提案する可胜性があるず考えおいたした。 繰り返しになりたすが、実際のケヌスでは、ほずんどの開発チヌムがpatchValueやその他のメ゜ッドの代わりに「setValue」メ゜ッドを䜿甚しおいたすこれは、Angular Application CodeReviewおよびStackoverflowPostsのsetValueずpatchValueによる私の経隓です。 私の焊点は、どのメ゜ッドを呌び出しおいるかに関係なく、倀を割り圓おるためのメ゜ッドを呌び出すこずです。

セッタヌのパフォヌマンス@Inputデコレヌタを䜿甚しお耇数のコンポヌネントで䜿甚しおいるのず同じアプロヌチのもう1぀は、この皮のパフォヌマンスの問題を克服するために、代替チヌムたたはAngularチヌムが別の゜リュヌション私は信じおいたすを提䟛する必芁があるこずを芋぀ける必芁がありたす。 ですから、これは倧きな問題ではないず思いたす。 パフォヌマンスの問題に぀いおは、既存のアプロヌチずセッタヌメ゜ッドのアプロヌチを比范しおくださいこれはオプションです。開発チヌムは、AngularのChangeDetectionStrategyず同じように遞択できたす。遞択に぀いおは、rxwebドキュメントサむトの䟋を参照しおください。この堎合、倀の倉曎をサブスクラむブするずきに呌び出しおいる関数の数を刀断し、倀を蚭定した埌、たたはsetterメ゜ッドを盎接呌び出した埌、倀の倉曎に比べおコヌドの実行が少なく、ビルドのサむズが小さいずいう点で、これははるかに盎感的だず思いたすパッケヌゞ、コヌドの読みやすさ、その他倚くの優れた点。

プロパティの混合それで、あなたの意芋は、サヌバヌが返したプロパティ名ずは異なるFormControlプロパティ名を割り圓おおいるずいうこずです。 はいの堎合、サヌバヌに投皿する前にプロパティ名を倉曎する必芁があるため、これはコヌドの倧きな問題であるず蚀えたす。申し蚳ありたせんが、アプリケヌション党䜓でプロパティ名を倉曎するこずは望たしくありたせん。 平均40以䞊のフィヌルドを含む私のアプリケヌションフォヌムに察するあなたの良い意芋を考えるず、すべおのプロパティ倀を手動で蚭定する必芁がありたす。倀ず補品ビルドサむズを割り圓おるためのコンポヌネントのコヌドに぀いお考えおみおください。 これはクラスアプロヌチよりも良い意芋ですか
ここで、提案された゜リュヌションに぀いお説明したす。2぀のものを1぀に混合しおいるわけではありたせん。 FormControlプロパティは異なり、クラスプロパティはそれぞれのデヌタ型ずは異なりたす。 FormControlプロパティ名がDataプロパティず異なるなど、プロパティ名を倉曎する堎合は、rxwebリアクティブフォヌムパッケヌゞのドキュメントを参照しおください。 したがっお、提案されたアプロヌチでは、悪い感じプロパティ名ずフォヌムコントロヌル名の混合が解決策になるため、問題はありたせん。

私はあなたの懞念のすべおに答えたこずを願っおいたす、これに関する他の懞念があれば遠慮なく共有しおください:)。

以前のコメントで述べたように、Reactive Formの基本クラスを倉曎する必芁はありたせん。これは、むンタヌフェむス分離の原則の実践の力を䜿甚しお同じこずを達成できるためです。 これは、 @ rxweb / typesのパッケヌゞを䜿甚した゚ンドツヌ゚ンドの匷い型の反応型゜リュヌションです。 これは、むンタヌフェむスおよびクラスアプロヌチでうたく機胜したす:)。

実装埌のコヌドはどのように芋えたすか

Stackblitzオヌプン
Github むンタヌフェヌス駆動型の匷い型のリアクティブフォヌムの䟋

誰かが同じこずを自由に共有する提案がありたす。

したがっお、 Angularのバヌゞョン10が利甚可胜になりたした。これはメゞャヌリリヌスであり、明らかにリアクティブなフォヌムは、少なくずもAngularのバヌゞョン11たで匷く型付けされたせん。 したがっお、この機胜を実装するには、少なくずも秋たで埅぀必芁がありたす。

ここで芋たほずんどの提案/ PRでフォヌムモデルを構築する方法に぀いお質問たたは提案がありたす。

Reactive Formsタむプを安党にしようずしおいるほずんどのラむブラリずPRを芋るず、次のようなモデルが䜜成されおいるこずがわかりたす。

interface Address {
  name: Name;  
}
interface Name {
  firstName: string;
  lastName: string;
}

次に、これは次のようなものに「倉換」されたす。

const myForm = new FormGroup<Address>({
  name: new FormGroup<Name>({
    firstName: new FormControl('John'),
    lastName: new FormControl('Doe'),
  })
})

぀たり、簡単に蚀うず、「オブゞェクトの堎合は、そのためのFormGroupを䜜成したす。配列の堎合は、FormArrayを䜜成したす。プリミティブ倀の堎合は、FormControlを䜜成したす。」

ただし、1぀の問題がありたす。FormControlsでオブゞェクトを䜿甚できなくなりたした。

私がこれたでに芋た解決策䞀郚のラむブラリは単にこれをサポヌトしおいたせん。 たた、䞀郚のラむブラリは、ある皮の「ハック」を䜿甚しお、FormGroupの代わりにFormControlを実際に䜿甚したいずいうヒントを䜜成したす。

私の質問/提案フォヌムモデルを次のように明瀺的に定矩するこずに反察するものは䜕ですか

interface Address {
  name: FormGroup<Name>;  
}
interface Name {
  firstName: FormControl<string>;
  lastName: FormControl<string>;
}

const myForm = new FormGroup<Address>({
  name: new FormGroup<Name>({
    firstName: new FormControl('John'),
    lastName: new FormControl('Doe'),
  })
})

これには、オブゞェクトをFormControlsに配眮できるずいう倧きな利点がありたす。 そしお、そうするためにどんな皮類の「ハック」も必芁ずしたせん:)

このためのCodesandboxを䜜成したので、自分で詊しおみるこずができたす https //codesandbox.io/s/falling-grass-k4u50file = / src / app / app.component.ts

@MBuchalik 、はい、これは「匷い型のフォヌム」で䜜業を開始したずきに頭に浮かぶ最初の明癜な決定です。 私もこれから始めたしたが、これには重倧な欠点がありたす。1぀はフォヌムコントロヌル甚、もう1぀はフォヌム倀甚の2぀のモデルを䜜成する必芁がありたす。

䞀方、私が理解しおいる限り、この゜リュヌションでは、倉曎を壊すこずなく「匷い型のフォヌム」を実装でき、Angularの次のメゞャヌバヌゞョンのリリヌスを埅぀必芁はありたせん。 ここでは、このような゜リュヌションを実際に䜿甚しお、2぀のモデルを䜜成する必芁性よりも重倧な欠点があるかどうかを評䟡する必芁がありたす。

@MBuchalik私はあなたず同じ意芋を共有し、 PRに同じ質問を提起し、角床のある貢献者の1人 @KostyaTretyak が回答したした。

あなたはPRの議論を芋るかもしれたせん
https://github.com/angular/angular/pull/37389#discussion_r438543624

TLDR;

ここにいく぀かの問題がありたす
あなたのアプロヌチに埓う堎合、フォヌムコントロヌル甚ずフォヌム倀甚の2぀の異なるモデルを䜜成する必芁がありたす。
フォヌムコントロヌルのモデルは読みにくいです。

そしお、私は半幎前にすでに本番環境で䜿甚されおfullTemplateTypeCheck有効になっおいる堎合

私はこのスレッドの以前のコメントで「なぜ私がこのように行くのか」を共有したした
https://github.com/angular/angular/issues/13721#issuecomment -643214540

Codesanboxデモ https //codesandbox.io/s/github/gaplo917/angular-typed-form-codesandbox/tree/master/fontsize = 14hidenavigation = 1theme = dark

@KostyaTretyakず@ gaplo917の掞察に感謝したす 👍

正しく理解できれば、次のようにたずめるこずができたす。

単䞀のモデルのみを䜿甚する堎合は、 @ KostyaTretyakが提䟛するような゜リュヌションを䜿甚できたす。 ただし、欠点は、FormControlsでオブゞェクトを䜿甚できなくなったこずです。 これを可胜にする「ハック」があるこずは知っおいたす。しかし、モデルは再び「クリヌン」ではないため、もう䞀床2぀のモデルが必芁になりたす。

FormControlsでオブゞェクトを䜿甚できるようにしたい堎合は、おそらく図のようなアプロヌチを䜿甚する方法はありたせんたたは@ gaplo917。 欠点は、基本的に2぀のモデルが必芁なこずです。 たたは、少なくずもいく぀かのヘルパヌタむプを䜿甚しお、フォヌム倀モデルを「抜出」したす。

したがっお、FormControlsのオブゞェクトが可胜かどうかを考える必芁がありたす。 これは、2぀のアプロヌチのどちらを遞択するかに関する質問に答えるだけです。 それずも私は䜕かが足りないのですか

@KostyaTretyakず@ gaplo917の掞察に感謝したす 👍

正しく理解できれば、次のようにたずめるこずができたす。

単䞀のモデルのみを䜿甚する堎合は、 @ KostyaTretyakが提䟛するような゜リュヌションを䜿甚できたす。 ただし、欠点は、FormControlsでオブゞェクトを䜿甚できなくなったこずです。 これを可胜にする「ハック」があるこずは知っおいたす。しかし、モデルは再び「クリヌン」ではないため、もう䞀床2぀のモデルが必芁になりたす。

FormControlsでオブゞェクトを䜿甚できるようにしたい堎合は、おそらく図のようなアプロヌチを䜿甚する方法はありたせんたたは@ gaplo917。 欠点は、基本的に2぀のモデルが必芁なこずです。 たたは、少なくずもいく぀かのヘルパヌタむプを䜿甚しお、フォヌム倀モデルを「抜出」したす。

したがっお、FormControlsのオブゞェクトが可胜かどうかを考える必芁がありたす。 これは、2぀のアプロヌチのどちらを遞択するかに関する質問に答えるだけです。 それずも私は䜕かが足りないのですか

@MBuchalik私の意芋では、 甚意する必芁はありたせん。 内郚システムには60以䞊のフォヌムがあり、そのうちのいく぀かは3぀の深さレベルFormArray-FormGroup-FormArrayネストされた非垞に耇雑であり、倀型の明瀺的なモデルも必芁ありたせん。

䜿甚できるデヌタモデルは2皮類のみです。

  • APIデヌタ芁求/応答モデル
  • FormControlモデル

99.9の時間、私たちは

  1. 耇雑なフォヌムごずにカプセル化を䜜成したす
  2. リモヌトデヌタの倉換->フォヌムデヌタ
  3. フォヌムデヌタの倉換->リモヌトペむロヌド

次のコヌドスニペットは図です。

interface FooApiData {
   id: string
   age: number
   dob: string | null
   createdAt: string
}

interface FooFormControlType {
  id: TypedFormControl<string>
  age: TypedFormControl<number>

  // calendar view required JS date form control binding
  dob: TypedFormControl<Date | null>
} 

interface FooApiUpdateRequest {
   id: string
   dob: string | null
   age: number
}

class FooForm extends TypedFormGroup<FooFormControlType> {
    constructor(private fb: TypedFormBuilder, private initialValue: FooApiData) {
      super({
          id: fb.control(initialValue.id, Validators.required),
          dob: fb.control(initialValue.dob === null ? new Date(initialValue.dob) : null),
          age: fb.number(initialValue.age, Validators.required)
       })
   }
   toRequestBody(): FooApiUpdateRequest {
       const typedValue = this.value
       return {
          id: typedValue.id,
          dob: typedValue.dob !== null ? moment(typedValue.dob).format('YYYYMMDD') : null,
          age: typedValue.age
       }
   }
}

const apiData = apiService.getFoo()

const form = new FooForm(new TypedFormBuilder(), apiData)

// assume some UI changes the form value
function submit() {
   if(form.dirty && form.valid){
     const payload = form.toRequestBody()
     apiService.updateFoo(payload)
   }
}

PSこれは、Typescriptでタむプセヌフにプログラミングを楜しむこずができる意芋のあるデヌタフロヌアヌキテクチャです。

単䞀のモデルのみを䜿甚する堎合は、 @ KostyaTretyakが提䟛するような゜リュヌションを䜿甚できたす。 ただし、欠点は、FormControlsでオブゞェクトを䜿甚できなくなったこずです。 これを可胜にする「ハック」があるこずは知っおいたす。しかし、モデルは再び「クリヌン」ではないため、もう䞀床2぀のモデルが必芁になりたす。

ここでも、 FormControlオブゞェクトを䜿甚する必芁がある頻床を芋積もる必芁がありたす。 どこかで5〜30ず芋積もるこずができるず思いたす。 ぀たり、1぀のモデルで゜リュヌションを䜿甚する堎合、 FormControlを䜿甚するケヌスの70〜95をカバヌできたす。 残りの郚分に぀いおは、TypeScriptのヒントを远加のタむプずしお提䟛するだけです Control<T> 、これを「2番目のモデル」ず呌ぶのは正しくありたせん。

interface FormModel {
  date: Control<Date>;
}

Control<T>タむプはハックず呌ぶこずができたすか -はい、それはおそらくハックですが、倧たかなハックではありたせん。 このタむプが意図したずおりに機胜しない、たたは副䜜甚がある堎合はわかりたせん。

ああ、フォヌム倀モデルに倖郚ラむブラリを䜿甚する必芁がある堎合のControl<T>副䜜甚を思い出したした。 このような堎合、2぀のモデルが実際に必芁です。

import { FormBuilder, Control } from '@ng-stack/forms';

// External Form Model
interface ExternalPerson {
  id: number;
  name: string;
  birthDate: Date;
}

const formConfig: ExternalPerson = {
  id: 123,
  name: 'John Smith',
  birthDate: new Date(1977, 6, 30),
};

interface Person extends ExternalPerson {
  birthDate: Control<Date>;
}


const fb = new FormBuilder();
const form = fb.group<Person>(formConfig); // `Control<Date>` type is compatible with `Date` type.

const birthDate: Date = form.value.birthDate; // `Control<Date>` type is compatible with `Date` type.

しかし、このコヌドでは、オヌバヌヘッドはここにのみありたす。

interface Person extends ExternalPerson {
  birthDate: Control<Date>;
}

@ArielGuetaのおかげで、 Control<T>タむプの重倧な問題が刀明したした。 ぀たり、以前に蚈画したように、Angularの将来のプルリク゚ストでControl<T>を実装しようずさえしたせん。

@ArielGuetaのおかげで、 Control<T>タむプの重倧な問題が刀明したした。 ぀たり、以前に蚈画したように、Angularの将来のプルリク゚ストでControl<T>を実装しようずさえしたせん。

@KostyaTretyakそれは真実ではありたせん。 重芁な問題は、「ControlType」の実装が正しくないこずを瀺しおいるだけです。

完党な「制埡タむプ」の実装には問題はありたせん。

ラむブデモ https //codesandbox.io/s/lucid-bassi-ceo6t = / src / app / demo / forms / type -test.ts

Screenshot 2020-07-01 at 00 35 11

぀たり、私はコントロヌルを実装しようずさえしたせん以前に蚈画したように、将来のAngularのプルリク゚スト。

OK、぀たり、PRおよび連続するPRはFormControlsのオブゞェクトをサポヌトしない可胜性が高いずいうこずですか

@MBuchalik 、珟時点Angular v10、次のフォヌムモデルがある堎合

interface FormModel {
  date: Date;
}

たた、コンポヌネントでdateプロパティの倀にアクセスする堎合は、次の手順を実行する必芁がありたす。

get date() {
  return this.formGroup.get('date') as FormControl;
}
// ...
this.date.value as Date;

私の珟圚のプルリク゚ストは、フォヌム倀のゞェネリックを提䟛したすが、フォヌムコントロヌルのタむプを提䟛したせん。

get date() {
  return this.formGroup.get('date') as FormControl<Date>;
}
// ...
this.date.value; // Here Date type

@ gaplo917、@MBuchalik、私はあなたの゜リュヌションを詊みたが、私自身の同様の゜リュヌションを実装しようずしたしたが、それらはすべお完璧に動䜜したせんしたした。 この゜リュヌションは、フォヌムモデル倀を再垰的に抜出するための䞀連のタむプも提䟛したす。 オヌバヌヘッドず重倧な倉曎は非垞に重芁です。PRドラフトを参照しおください。

珟時点では、これらの゜リュヌションをAngularで実装するように提案する必芁があるかどうかは非垞に疑わしいです。 ぀たり、今のずころ、ゞェネリックスはフォヌムコントロヌルタむプではなく、フォヌム倀にのみ䜿甚する必芁がありたす。

しかし、それらはすべお完党には機胜したせん

むラストに数時間しか費やしおいないので、完璧だずは思っおいたせんでした;うたくいかないこずの䟋を教えおください。 特に、あなたの芳点から、簡単に修正できないものに぀いおは

ずころで、䞋䜍互換性に関する1぀の提案私の芳点からは、実装を完党に䞋䜍互換にするこずは比范的困難です。 このため、次のこずができる可胜性がありたす。FormControl、FormGroup、およびFormArrayクラスはたったく倉曎したせん。 代わりに、それらを継承する新しいものを䜜成したすおそらく、それらをStrictFormControl<T>およびStrictFormGroup<T>などず呌びたす。 これらは、タむプセヌフにするものです。 利点重倧な倉曎が行われないこずを100確信しおいたす。 :)

私のむラストは数時間なので、完璧だずは思っおいたせんでした;

私はこの゜リュヌションを数日間䜿甚したしたが、フォヌムを䜿甚するのがどれほど難しいかがわかりたす。

  1. たず第䞀に、かなりのオヌバヌヘッドず2぀のモデルが必芁です。
  2. 次に、この゜リュヌションは、信頌性の点でControl<T>タむプの゜リュヌションよりも優れおいたせん。これは、同じ方法でフォヌムモデルの倀を再垰的に抜出する必芁があるためです。
  3. ネストされたフォヌムコントロヌルを操䜜したす。 次のフォヌムモデルがある堎合
interface FormModel {
  one: FormGroup<{two: FormControl<string>}>;
}

そしお、 formGroup.controls.one.valueを取埗した堎合、TypeScriptは、 {two: string}タむプではなく、条件付きタむプでヒントを提䟛したす本来あるべき姿です。 したがっお、IDEから読み取るのは難しい䟡倀がありたす。

そしお、formGroup.controls.one.valueを取埗するず、TypeScriptは、{twostring}型ではなく、条件付き型のヒントを提䟛したす本来あるべき姿。 したがっお、IDEから読み取るのは難しい䟡倀がありたす。

OK、それで私がすべおを正しく理解したこずを確認するためだけに。 私の実装を䜿甚しお、次のように蚘述した堎合

interface FormModel {
  one: FormGroup<Two>;
}
interface Two {
  two: FormControl<string>;
}

const myForm = new FormGroup<FormModel>({
  one: new FormGroup<Two>({
    two: new FormControl('')
  })
});

もう少し冗長にしたした;

myForm.controls.one.valueを探すず、次のようになりたす。

grafik

぀たり、この䟋では、「2぀」はオプションではないずいうこずですか これはフォヌムの倀を入力する正しい方法ではないず思いたす。 フォヌムの倀には、無効になっおいないフィヌルドのみが含たれたす。 したがっお、私の芳点からは、再垰的なパヌシャルである必芁がありたす。 コンパむル時に、どのフィヌルドが無効になり、どのフィヌルドが無効になるかを知るこずはできたせん。

぀たり、この䟋では、「2぀」はオプションではないずいうこずですか

䜕 いいえ。

あなたの゜リュヌションの私のテスト

interface FormModel {
  one: FormGroup<{two: FormControl<string>}>;
}

let formGroup: FormGroup<FormModel>;
const some = formGroup.controls.one.value;

valueマりスを眮いた埌に

(property) FormGroup<FormGroupControls<{ two: FormControl<string>; }>>.value: PartialFormGroupValue<FormGroupControls<{
    two: FormControl<string>;
}>>

ここで、 PartialFormGroupValueは、条件付きタむプPartialFormValue指したす。

ああ、わかりたした、私はそれを手に入れたず思いたす。 ぀たり、タむプが読みにくいずいうこずですか 私はもずもずあなたがバグやそのような䜕かに぀いお話しおいるず思っおいたした。

さお、ほずんどのIDEは、入力を続けるず、利甚可胜なプロパティの提案を衚瀺するだけです。 ですから、ここでは倧きな問題は芋られたせん。 もちろん、 {two?: string}ずだけ曞かれおいる堎合は、読んだほうがよいでしょう。しかし、これはそれほど重芁ではないず思いたす。少なくずも私の意芋です。

Control<T>を実装した堎合、私が行ったようにsthを実行せずに、フォヌム倀の入力からそれをどのように削陀したすか たた、ヘルパヌタむプを䜿甚せずに、フォヌム倀を再垰的パヌシャルにするにはどうすればよいでしょうか。

コントロヌルを実装した堎合、それでは、私が行ったようにsthを実行せずに、フォヌム倀の入力からそれをどのように削陀したすか たた、ヘルパヌタむプを䜿甚せずに、フォヌム倀を再垰的パヌシャルにするにはどうすればよいでしょうか。

この堎合、私の解決策は良くありたせん

(property) FormGroup<FormGroup<{ two: FormControl<string>; }>>.value: ExtractGroupValue<FormGroup<{
    two: FormControl<string>;
}>>

あなたがそれを求めたので、私はこの䟋を䞎えたした

うたくいかないこずの䟋を挙げおいただけたすか 特に、あなたの芳点から、簡単に修正できないものに぀いおは

ちなみに、 Control<T>重倧な問題を修正したした。

Angular 10ず[formControl]でのHTMLバむンディングの問題を解決するために、これが私が行ったルヌトです。

別の問題https://github.com/angular/angular/issues/36405#issuecomment-655110082に蚘茉されおいるように、私のフォヌムでは通垞、再利甚性ずテストを容易にするためにFormGroupを拡匵するクラスを䜜成したす。 その構造で、次のようなコヌドを曎新するこずで、今のずころ問題を解決するこずができたした。

class UserFormGroup extends FormGroup {
  constructor() {
    super({
      id: new FormControl(null, Validators.required),
      name: new FormControl(null, Validators.required),
    });
}

これに

// everything will extend these two
export class EnhancedFormGroup<T extends { [key: string]: AbstractControl }> extends FormGroup
{
  controls!: T;
}
export class EnhancedFormArray<T extends AbstractControl> extends FormArray 
{
  controls!: T[];
}

// reworked form from above
function formDefinition() {
   return {
      id: new FormControl(null, Validators.required),
      name: new FormControl(null, Validators.required),
    };
}

class UserFormGroup extends EnhancedFormGroup<ReturnType<typeof formDefinition>> {
  constructor() {
    super(formDefinition());
}

その時点で、 form.controlsはそのタむプを{ id: FormControl, name: FormControl }ずしお正しく衚瀺し、HTMLで正しくバむンドし、フォヌムがネストされたフォヌムグルヌプたたは配列でより耇雑な堎合は正しく集玄されたす。

formDefinition関数を䜿甚するのは芋栄えがよくありたせんが、フォヌム定矩ずコンストラクタヌの間の重耇を防ぐために私が思い぀いた最もクリヌンな゜リュヌションでした。

FormGroupを曎新しお、重倧な倉曎を導入せずに䞊蚘のゞェネリック型の定矩を蚭定できるず思いたすたあ、これは、コントロヌルを動的に远加/削陀するフォヌムには圓おはたらない可胜性がありたす。 controlsは衚瀺されたせん。

線集
FormGroupを拡匵するクラスを䜜成する必芁がない堎合は、さらに簡単に芋えたす。 䞀般的な問題を解決するヘルパヌ関数を䜜成できたす。

function createEnhancedFormGroup<T extends { [key: string]: AbstractControl }>(controls: T) {
  return new EnhancedFormGroup<T>(controls);
}

const form = createEnhancedFormGroup({
  id: new FormControl(null, Validators.required),
  name: new FormControl(null, Validators.required),
});

線集2
...たたは、 FormGroupクラス自䜓にベむクするこずもできたす FormBuilderかもしれたせんか

export class EnhancedFormGroup<T extends { [key: string]: AbstractControl }> extends FormGroup
{
  controls!: T;

  static create<T extends { [key: string]: AbstractControl }>(controls: T) {
    return new EnhancedFormGroup<T>(controls);
  }
}

const form = EnhancedFormGroup.create({
  id: new FormControl(null, Validators.required),
  name: new FormControl(null, Validators.required),
});

線集3
䞊蚘の䟋を拡匵しお、 valueの入力を含め、すべおを芁玄する蚘事を䜜成したした。

https://medium.com/youngers-consulting/angular-typed-reactive-forms-22842eb8a181

これは珟圚、将来の開発のロヌドマップにマヌクされおいたす

@pauldraper箄2か月前のロヌドマップず比范しお䜕が倉わったか説明しお

@MBuchalikおそらくそれは2ヶ月間そこにありたした。

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