プロジェクト内のフォームの動作の標準化(角度)



ユーザーフレンドリーなインターフェイスを作成するには、アプリケーション内のすべてのフォームが一貫して動作することを確認する必要があります。単調な動作は、暗黙的ではありますが、反復的なコードによって実現されることがよくあります。開発を簡素化し、フォームの動作を標準化すると思うパターンのスケッチを共有しましょう。



プロジェクトでフォームを送信するためのコードがこれに類似している場合は、catの下を確認することをお勧めします。



onSubmit():void
// login.component.ts
// bad practices
onSubmit(): void {
  this.formSubmitted = true;
  this.isUnhandledServerError = false;
  if (!this.formGroup.valid) return;
  this.isLoading = true;
  const { username, password } = this.formGroup.value;
  this.login(username, password)
    .pipe(finalize(() => (this.isLoading = false)))
    .subscribe({ error: error => this.handleError(error) });
}




コードが好きな人のために:

リファクタリングする前にstackblitzでプロジェクトしてください。

リファクタリング後のStackblitzプロジェクト。



問題の説明



フォームでは、多くのニュアンスを考慮する必要があります。機能的な観点から、フォームはユーザーが入力した情報をサーバーに送信するだけです。ただし、高品質のUXを確保するには、すべてに加えて、検証、サーバーからのエラーの表示、読み込みインジケーターなどを実行する必要があります。実際には、これらの詳細は開発者によって見落とされることが多く、アプリケーションの使いやすさに悪影響を与えるか、コードの重複を招き、フォームの開発を耐え難いルーチンに変えます。



これは、UXの観点からは良いが、開発の観点からは悪いフォーム送信ハンドラーの例です。リファクタリング前のStackblitzプロジェクト。



// login.component.ts
onSubmit(): void {
  this.formSubmitted = true; //   
  this.isUnhandledServerError = false; //       
  if (!this.formGroup.valid) return; //  
  this.isLoading = true; //   
  const { username, password } = this.formGroup.value;
  this.login(username, password) //    
    .pipe(finalize(() => (this.isLoading = false))) //   
    .subscribe({ error: error => this.handleError(error) });
}


ご覧のとおり、このハンドラーはUXを構成する多くの詳細を考慮に入れています。唯一の問題は、このアプローチでは、これらのニュアンスをアプリケーションのフォームごとに記述する必要があることです。



決定



開発を簡素化し、アプリケーション内のフォームの動作を標準化するには、フォーム送信ハンドラーコードを別のクラスに移動する必要があります。リファクタリング後のStackblitzプロジェクト。(この例のコードは意図的に簡略化しています。実際のプロジェクトでは、すべてのブールフィールドをObservableに置き換える必要があります。)



class Form<T> {
    submitted = false;

    pending = false;

    hasUnhandledServerError = false;

    constructor(private formGroup: FormGroup, private action: (value: any) => Observable<T>) {}

    submit(): Observable<T> {
        if (this.pending) return EMPTY;
        this.submitted = true;
        this.hasUnhandledServerError = false;
        if (this.formGroup.valid) {
            this.pending = true;
            return this.action(this.formGroup.value).pipe(
                tap({ error: () => (this.hasUnhandledServerError = true) }),
                finalize(() => (this.pending = false)),
            );
        }
        return EMPTY;
    }
}


したがって、ほとんどのUX機能を1つのクラスに集中させ、重複するロジックを取り除きます。これで、新しいフォームの作成にかかる時間が短縮され、Formクラスのみを変更することで、アプリケーション全体でフォームの動作を完了することができます。



図書館に置いてみませんか?



各プロジェクトのUX要件は固有であり、設計者によって異なります。顧客の要求に応じて、標準のマテリアル要素の動作をオーバーライドする必要がありました。したがって、1つのライブラリを使用してすべてのアプリケーションでフォームの動作を標準化する方法がわかりません。インターフェイスの動作は、設計者と開発者に任せてください。ただし、UX関連のロジックを別々のクラスに分けるのは良い考えだと思います。



この例がお役に立てば幸いです。プロジェクトでこのアイデアを使用してみてください。ながら!



All Articles