详谈Angular 2+ 的表单(一)之模板驱动型表单

在企业应用开发时,表单是一个躲不过去的事情,和面向消费者的应用不同,企业领域的开发中,表单的使用量是惊人的。这些表单的处理其实是一个挺复杂的事情,比如有的是涉及到多个 Tab 的表单,有的是向导形式多个步骤的,各种复杂的验证逻辑和时不时需要弹出的对话框等等。笔者试图在这一系列文章中对 Angular 中的表单处理做一个相对完整的梳理。

Angular 中提供两种类型的表单处理机制,一种叫模版驱动型(Template Driven)的表单,另一种叫模型驱动型表单( Model Driven ),这后一种也叫响应式表单 ( Reactive Forms ),由于模版驱动中有一个 ngModel 的指令,容易和这里说的模型驱动混淆,所以在我们的文章中叫后一种说法:响应式表单。

第一篇主要介绍模版驱动型的表单。

号外

本文评论区会抽出5位童鞋,赠送笔者的 《Angular 从零到一》纸书,机不可失,大家踊跃发言哦。

模版驱动的表单

模版驱动的表单和 AngularJS 对于表单的处理类似,把一些指令(比如 ngModel )、数据值和行为约束(比如 require 、 minlength 等等)绑定到模版中(模版就是组件元数据 @Component 中定义的那个 template ),这也是模版驱动这个叫法的来源。总体来说,这种类型的表单通过绑定把很多工作交给了模版。

模版驱动的例子

还是用例子来说话,比如我们有一个用户注册的表单,用户名就是 email ,还需要填的信息有:住址、密码和重复密码。这个应该是比较常见的一个注册时需要的信息了。那么我们第一步来建立领域模型:

// src/app/domain/index.ts export interface User { // 新的用户id一般由服务器自动生成,所以可以为空,用 ? 标示 id?: string; email: string; password: string; repeat: string; address: Address; } export interface Address { province: string; // 省份 city: string; // 城市 area: string; // 区县 addr: string; // 详细地址 }

接下来我们建立模版文件,一个最简单的 HTML 模版,先不增加任何的绑定或事件处理:

<!-- template-driven.component.html --> <form novalidate> <label> <span>电子邮件地址</span> <input type="text" placeholder="请输入您的 email 地址"> </label> <div> <label> <span>密码</span> <input type="password" placeholder="请输入您的密码"> </label> <label> <span>确认密码</span> <input type="password" placeholder="请再次输入密码"> </label> </div> <div > <label> <span>省份</span> <select> <option value="">请选择省份</option> </select> </label> <label> <span>城市</span> <select> <option value="">请选择城市</option> </select> </label> <label> <span>区县</span> <select> <option value="">请选择区县</option> </select> </label> <label> <span>地址</span> <input type="text"> </label> </div> <button type="submit">注册</button> </form>

渲染之后的效果就像下面这样:

#1f872bb245d9d0de23e6d546d8a82a0e#

 

简单的Form

数据绑定

对于模版驱动型的表单处理,我们首先需要在对应的模块中引入 FormsModule ,这一点千万不要忘记了。

import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from "@angular/forms"; import { TemplateDrivenComponent } from './template-driven/template-driven.component'; @NgModule({ imports: [ CommonModule, FormsModule ], exports: [TemplateDrivenComponent], declarations: [TemplateDrivenComponent] }) export class FormDemoModule { } 进行模版驱动类型的表单处理的一个必要步骤就是建立数据的双向绑定,那么我们需要在组件中建立一个类型为 User 的成员变量并赋初始值。 // template-driven.component.ts // 省略元数据和导入的类库信息 export class TemplateDrivenComponent implements OnInit { user: User = { email: '', password: '', repeat: '', address: { province: '', city: '', area: '', addr: '' } }; // 省略其他部分 }

有了这样一个成员变量之后,我们在组件模版中就可以使用 ngModel 进行绑定了。

令人困惑的 ngModel

我们在 Angular 中可以使用三种形式的 ngModel 表达式: ngModel , [ngModel] 和 [(ngModel)] 。但无论那种形式,如果你要使用 ngModel 就必须为该控件(比如下面的 input )指定一个 name 属性,如果你忘记添加 name 的话,多半你会看到下面这样的错误:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypgjd.html