Standardisierung des Verhaltens von Formularen im Projekt (Angular)



Um eine benutzerfreundliche Oberfläche zu erstellen, müssen Sie sicherstellen, dass sich alle Formulare in Ihrer Anwendung konsistent verhalten. Monotones Verhalten wird oft durch sich wiederholenden Code erreicht, wenn auch implizit. Lassen Sie mich eine Skizze eines Musters teilen, das meiner Meinung nach die Entwicklung vereinfacht und das Formularverhalten standardisiert.



Wenn der Code zum Senden von Formularen in Ihrem Projekt diesem ähnlich ist, empfehle ich Ihnen, unter cat nachzuschauen.



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) });
}




Für diejenigen, die Code einfach lieben:

Vor dem Refactoring auf Stackblitz projizieren.

Stackblitz-Projekt nach dem Refactoring.



Beschreibung des Problems



Formen erfordern die Berücksichtigung vieler Nuancen. Aus funktionaler Sicht sendet das Formular nur die vom Benutzer eingegebenen Informationen an den Server. Um jedoch eine qualitativ hochwertige UX zu gewährleisten, müssen Sie zusätzlich zu allem eine Validierung durchführen, Fehler vom Server anzeigen, eine Ladeanzeige usw. In der Praxis werden diese Details von Entwicklern häufig übersehen, was sich entweder negativ auf die Benutzerfreundlichkeit der Anwendung auswirkt oder zu einer Codeduplizierung führt und die Formularentwicklung zu einer unerträglichen Routine macht.



Hier ist ein Beispiel für einen Formularübermittlungs-Handler, der aus UX-Sicht gut, aus Entwicklungssicht jedoch schlecht ist. Stackblitz-Projekt vor dem Refactoring.



// 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) });
}


Wie Sie sehen können, berücksichtigt dieser Handler viele Details, aus denen sich die UX zusammensetzt. Das einzige Problem ist, dass bei diesem Ansatz diese Nuancen für jedes Formular in der Anwendung geschrieben werden müssen.



Entscheidung



Um die Entwicklung zu vereinfachen und das Verhalten von Formularen in Ihrer Anwendung zu standardisieren, müssen Sie den Code für den Formularübermittlungs-Handler in eine separate Klasse verschieben. Stackblitz-Projekt nach dem Refactoring. (Ich habe den Code für das Beispiel absichtlich vereinfacht. In einem realen Projekt müssen Sie alle booleschen Felder durch Observable ersetzen.)



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;
    }
}


Daher konzentrieren wir die meisten UX-Funktionen auf eine Klasse und entfernen doppelte Logik. Das Schreiben eines neuen Formulars nimmt jetzt weniger Zeit in Anspruch, und Sie können das Verhalten von Formularen in der gesamten Anwendung vervollständigen, indem Sie nur die Formularklasse ändern.



Warum nicht in die Bibliothek stellen?



Die UX-Anforderungen für jedes Projekt sind einzigartig und hängen mehr vom Designer ab. Auf Kundenwunsch musste ich bereits das Verhalten von Standardmaterialelementen außer Kraft setzen. Daher sehe ich keine Möglichkeit, das Verhalten von Formularen in allen Anwendungen mit einer Bibliothek zu standardisieren. Lassen Sie das Verhalten der Benutzeroberfläche dem Designer und den Entwicklern ausgeliefert bleiben. Ich halte es jedoch für eine gute Idee, UX-bezogene Logik in separate Klassen zu unterteilen.



Ich hoffe, das Beispiel war hilfreich und Sie werden versuchen, die Idee in Ihren Projekten zu verwenden. Tschüss!



All Articles