Angular们,还在手写表单吗?要不试试这个好东西

363 阅读4分钟

传统开发表单

使用Angular开发项目的时候,如遇到表单的开发场景,则一般的工作流程是这样的:

  1. 从其他地方copy相似代码到html里,然后修改html里的label、formControlName、placeholder等。

    <form nz-form [formGroup]="validateForm">
      <nz-form-item>
        <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="superior">上级</nz-form-label>
        <nz-form-control [nzSm]="14" [nzXs]="24">
            <input nz-input formControlName="superior" id="superior" placeholder="上级" />
        </nz-form-control>
      </nz-form-item>

      <nz-form-item>
        <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="title">名称</nz-form-label>
        <nz-form-control [nzSm]="14" [nzXs]="24" [nzErrorTip]="combineTpl">
          <input nz-input formControlName="title" autocomplete="off" id="title" placeholder="请输入名称" />
        </nz-form-control>
      </nz-form-item>
      <ng-template #combineTpl let-control>
        <ng-container *ngIf="control.hasError('maxlength')">输入的字数超出限制</ng-container>
        <ng-container *ngIf="control.hasError('required')">请输入名称</ng-container>
      </ng-template>
    </form>
  1. 注入fb,在ngOnInit里初始化表单:
constructor(
    ...
    private fb: FormBuilder,
  ) { }

  ngOnInit(): void {
    this.validateForm = this.fb.group({
      superior: [null],
      title: [null, [Validators.required, Validators.maxLength(10)]],
      ...
    });
  }
  1. 复杂场景为了达到业务需求,你可能还需要

// 监听控件的变化
this.validateForm.get('superior').valueChanges.subscribe((val) => {
  ...
})

// 禁用启用
this.validateForm.get("superior").disable();
this.validateForm.get("title").enable();

// 设值取值
this.validateForm.get('superior').setValue(superiorName);
const val = this.validateForm.get('title').value;

// 等等

4.提交表单时候验证:

    for (const i in this.validateForm.controls) {
      this.validateForm.controls[i].markAsDirty();
      this.validateForm.controls[i].updateValueAndValidity();
    }

5.表单回显:

    this.validateForm.patchValue({
      title: data.title,
      superior: data.superior,
      ...
    })

你的组长或者上级在做技术分享的时候肯定跟你解释过什么是前端工程化?

利用工具链解决前端在开发过程中提升效率和质量的问题。所有能降低成本,并且能提高效率的事情都属于工程化的范畴。

那上面的工作流程?

  • 使用了工具链吗?没有
  • 提升了效率了吗?手写了一大堆html等模板代码,没有
  • 提升了质量了吗?手写表单控件和各种逻辑导致代码量大,难以维护。答曰没有
  • 降低了成本了吗?花了这么多时间写模板代码。答曰没有(摸鱼的时间减少了

那类似于表单工作场景有没有标准的工具链来提高效率、质量同时降低成本呢?答曰 有

破局

Formly是Angular的一个动态(JSON驱动)表单库,为应用程序的表单带来无与伦比的可维护性。

Formly提供了一种声明式的表单构建方式,允许开发者通过配置对象来定义表单控件,而不是直接编写HTML和CSS代码。这样做的好处包括:

  • 动态表单生成:可以很容易地根据模型动态地创建和修改表单。
  • 高度复用性:配置可以复用于不同的表单和应用程序。
  • 减少代码量:通过配置而不是编码,可以显著减少代码量。
  • 易于测试:表单逻辑和控件分离,使得测试更加容易。
  • 样式灵活:可以通过CSS定制表单样式,而且更容易实现一致性。

并且UI和Formly解耦,你可以选择任意的组件库的表单组件来渲染表单,是不是酷毙了。 目前官方支持以下UI:

  • Bootstrap
  • Material
  • Ionic
  • PrimeNG
  • Kendo

上面的这些UI真心不怎么好看,国内基本没人使用。

V6版本新增支持ng-zorro-antd。不过官方仅仅是适配了。离生产环境还很远,因为它只支持这几个控件:input、textarea、checkbox、radio、select。

那有没有开源的Formly的ng-zorro主题UI呢?毕竟使用Angular技术栈的公司,基本都用ng-zorro-antd组件库。

符合工程化的开发表单流程

Formly的ng-zorro主题UI:ngx-ng-zorro-formly。它支持几乎所有的表单组件,支持ng-zorro-antd表单组件上的几乎所有的配置项。提供了五种布局:卡片、标签页、穿梭框、折叠面板、子表,还提供了开发中场景的业务场景逻辑示例如:取值赋值、隐藏显示、禁用启用、必填不必填、子表主表联动等。

那使用这个库的工作流程是:

  1. 引入Formly和ngx-ng-zorro-formly(这一步仅项目初始化时引入一次)
  2. 引入表单渲染组件:
<formly-form-template 
    #formlyFormTemplate
    [configs]="configs"
></formly-form-template>

3.传入configs

import { Component, OnInit } from '@angular/core';
import { FormlyFieldConfig } from '@ngx-formly/core';
import { FormlyFormTemplateComponent } from 'ng-zorro-formly';

@Component({
  selector: 'app-root',
  template: `
    <formly-form-template 
      #formlyFormTemplate
      [configs]="configs"
    ></formly-form-template>
  `,
  styleUrls: ['./app.component.less']
})
export class AppComponent implements OnInit {
  @ViewChild('formlyFormTemplate') formlyFormTemplate: FormlyFormTemplateComponent;
  configs: FormlyFieldConfig[] = []

  ngOnInit(): void {
    this.configs = [
    ...控件配置
    ]

  }

  submit() {
    const valid = this.formlyFormTemplate.validForm();
    if (valid) {
      const model = this.formlyFormTemplate.submit();
      console.log('model >>:', model);
    }
  }
}

结语

关于更多Formly的配置项和examples请访问:v5.formly.dev/

UI-ng-zorro-antd库引入:github.com/zzhimin/ngx…

UI-ng-zorro-antd配置参考:zzhimin.github.io/ngx-ng-zorr…

觉得有帮助的Angular们,欢迎start一下啊。