要创建用户友好的界面,您需要确保应用程序中的所有表单行为一致。单调的行为通常是通过重复代码来实现的,尽管是隐式的。让我分享一个模式的草图,我认为它可以简化开发并标准化表单的行为。
如果您的项目中提交表单的代码与此类似,建议您注意一下。
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相关的逻辑分为单独的类是一个好主意。
我希望该示例对您有所帮助,并且您将尝试在项目中使用该想法。而!