规范项目中表单的行为(角度)



要创建用户友好的界面,您需要确保应用程序中的所有表单行为一致。单调的行为通常是通过重复代码来实现的,尽管是隐式的。让我分享一个模式的草图,我认为它可以简化开发并标准化表单的行为。



如果您的项目中提交表单的代码与此类似,建议您注意一下。



onSubmit():无效
// 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功能集中在一类中,并消除了重复的逻辑。现在,编写新表单将花费更少的时间,并且您只需更改Form类就可以完成整个应用程序中表单的行为。



为什么不把它放进图书馆呢?



每个项目的UX需求都是唯一的,并且在很大程度上取决于设计人员。我已经必须根据客户的要求覆盖标准Material元素的行为。因此,我看不到任何使用一个库来标准化所有应用程序中表单行为的方法。让界面的行为留在设计人员和开发人员手中。但是,我认为将与UX相关的逻辑分为单独的类是一个好主意。



我希望该示例对您有所帮助,并且您将尝试在项目中使用该想法。而!



All Articles