文档章节

angular6 中怎样创建响应式表单?

IrisHuang
 IrisHuang
发布于 07/13 12:10
字数 1299
阅读 30
收藏 0

在angular中,提供了两种创建表单的方式:

  • 模板驱动型表单(Template Driven Forms)
  • 响应式表单(Reactive Forms)

在模板驱动型表单中,我们直接通过 ngModel 指令在组件模板中创建 control 和绑定数据,不用创建控件、表单对象或编写代码来处理组件类和模板之间的数据交流;并且,我们不会把表单验证写在组件类中。

在响应式表单中,我们在组件类中创建表单对象,并将其绑定到模板中的响应式表单控件中。所有的表单控件和数据验证都写在组件类中;表单验证和表单状态变化是异步的,我们可以在组件类写代码中观察到这一点。响应式表单通常用于数据模型确定的情形。

那么这两种创建表单的方式主要区别在哪里呢?

在响应式表单中,我们不需要用到ngModel,required等指令,我们在组件类中创建所有的控件和验证器。它很容易测试和维护。接下来,我将通过FormControl/FormGroup/FormBuilder/FormArray和添加一些表单验证功能来创建一个响应式表单。

step1: 添加响应式表单模块:Reactive Forms Module

import {ReactiveFormsModule} from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule, ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

step2: 在组件中引入要求的类

我们需要先在组件类中引入 FormGroup, FormControl, FormArray类,这些都是帮助我们创建响应式表单的神兵利器。

import { Component } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms';
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'Reactive Forms Demo';
}

step3: 引用 FormControl 类

FormControl类对应一个单独的表单控件,跟踪它的值和有效性。当我们创建表单时,我们会创建一个FormControl的对象。如下:我们在组件类中创建了一个FormControl对象;

export class AppComponent {
    email = new FormControl('');
}

在模板中,我们通过属性绑定将email表单控件绑定到input元素上。

<input [formControl]='email' type="text" placeholder="Enter Email"/>
{{email.value | json}}

step4: 使用 FormGroup 类

FormGroup是多个FormGroup的集合,提供了一个追踪一组表单控件的值或是验证的API。它作为表单视图层的最高级,我们可以将FormGroup作为一个单独的对象,然后每个form control都看作是它的一个属性。创建一个FormGroup,如下:

loginForm = new FormGroup({
    email: new FormControl(' '),
    password: new FormControl(' ')
})

在这里我们创建了一个登陆表单,它有两个表单控件:email和password。对应的视图为:

<form [formGroup]='loginForm' novalidate class="form">
    <input formControlName='email' type="text" class="form-control"
           placeholder="Enter Email" />
    <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
</form>
{{loginForm.value | json}}
{{loginForm.status | json }}

这里,我们采用了属性绑定将formcontrolName指令和组件类中的formControl绑定起来。如果你曾经用过模板驱动型表单,会发现这没有ngModel或是name绑定到元素上。我们还可以直接通过值和状态属性来查看表单的值和状态。

step5: 提交表单

如果要提交表单,我们需要增加一个提交按纽,并且绑定提交处理函数;如下:

<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
    <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
    <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
    <button class="btn btn-default">Login</button>
</form>

在组件类中,添加表单提交处理函数loginUser():

export class AppComponent implements OnInit {
    loginForm: FormGroup;
    ngOnInit() {
        this.loginForm = new FormGroup({
            email: new FormControl(null, Validators.required),
            password: new FormControl()
        });
    }
    loginUser() {
        console.log(this.loginForm.status);
        console.log(this.loginForm.value);
    }
}

step6: 添加表单验证

要添加表单验证,需先引入angular/forms中的Validators,如下:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, Validators.required),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)])
    });
}

在模板中,我们通过FormGroup发现某个control的错误,在下面,我们检查表单验证结果并且用隐藏的div显示错误。如下:

<div class="container">
    <br />
    <form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
        <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
        <div class="alert  alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
            Email is required
        </div>
        <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
        <div class="alert  alert-danger" *ngIf=" !loginForm.get('password').valid && loginForm.get('email').touched">
            Password is required and should less than 10 characters
        </div>
        <button [disabled]='loginForm.invalid' class="btn btn-default">Login</button>
    </form>
</div>

step7: 使用 FormBuilder

FormBuilder 用来简化FormGroup和FormControl之间的语法。当表单特别长的时候,这个类尤其有效。注入进组件中,如下:

constructor(private fb : FormBuilder){}

用它创建响应式表单如下:

this.loginForm = this.fb.group({
    email: [null, [Validators.required, Validators.minLength(4)]],
    password: [null, [Validators.required, Validators.maxLength(8)]]
})

组件类中的所有代码如下:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators, FormBuilder } from '@angular/forms';
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
    loginForm: FormGroup;
    constructor(private fb: FormBuilder) {
    }
    ngOnInit() {
        this.loginForm = this.fb.group({
            email: [null, [Validators.required, Validators.minLength(4)]],
            password: [null, [Validators.required, Validators.maxLength(8)]]
        })
    }
    loginUser() {
        console.log(this.loginForm.status);
        console.log(this.loginForm.value);
    }
}

总结

创建响应式表单主要用到FormControl/FormGroup/FormBuilder/FormArray这几类,同时需要先引入响应式表单模块:ReactiveFormsModule。上面几个类之间的关系为:

参考:https://dzone.com/articles/how-to-create-reactive-forms-in-angular

© 著作权归作者所有

共有 人打赏支持
IrisHuang
粉丝 2
博文 58
码字总数 28246
作品 0
武汉
前端工程师
私信 提问
Angular6笔记之封装http

最近抽空学习了一下Angular6,之前主要使用的是vue,所以免不了的也想对Angular6提供的工具进行一些封装,今天主要就跟大家讲一下这个http模块。 之前使用的ajax库是axios,可以设置baseurl...

ma125120
07/27
0
0
Angular6封装http请求

最近抽空学习了一下Angular6,之前主要使用的是vue,所以免不了的也想对Angular6提供的工具进行一些封装,今天主要就跟大家讲一下这个http模块。 之前使用的ajax库是axios,可以设置baseurl...

_marven
08/12
0
0
【Angular】——表单处理

纯HTML表单:显示表单项,校验用户输入,提交表单数据。就是普通写的HTML页面。 模板式表单:表单的数据模型是通过组件模板中的相关指令来定义的。因为使用这种方式定义表单的数据模型时,我...

fjj15732621696
03/18
0
0
细说 Angular 2+ 的表单(二):响应式表单

细说 Angular 2+ 的表单(一):模板驱动型表单 响应式表单 响应式表单乍一看还是很像模板驱动型表单的,但响应式表单需要引入一个不同的模块: 而不是 与模板驱动型表单的区别 接下来我们还...

接灰的电子产品
2017/06/13
0
0
十大前端开发框架(下)

本文由伯乐在线 -厉瑶 翻译。未经许可,禁止转载! 英文出处:Site Point。欢迎加入翻译组。 在《十大前端开发框架(上)》中我们了解了跟Bootstrap相关的一系列前端开发框架,如果你对于Boo...

伯乐在线
2013/07/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

IC-CAD Methodology企业实战之openlava

在云计算解决安全问题并成为IC界主流运算平台之前,私有的服务器集群系统仍然是各大IC公司的计算资源平台首选。 现在主流的服务器集群管理系统包括lsf,openlava,SkyForm,三者都属于lsf一系...

李艳青1987
24分钟前
0
0
http response stream 字节流 接收与解码

在接收图片、音频、视频的时候,需要用到二进制流。 浏览器会发给客户端 字节Byte流,一串串的发过来_int8格式 -128~127(十进制),也就是8bit(位)。 客户端接收的时候,对接收到的字节收集,...

大灰狼wow
24分钟前
0
0
配置Tomcat监听80端口...

12月13日任务 16.4 配置Tomcat监听80端口 16.5/16.6/16.7 配置Tomcat虚拟主机 16.8 Tomcat日志 1.配置Tomcat监听80端口 示例一:自定义监听端口 vim /usr/local/tomcat/conf/server.xml 编辑...

hhpuppy
25分钟前
0
0
在ubuntu中配置java环境

先在官网下载一个jdk 进入root权限,避免之后出现创建文件失败或者修改文本失败的问题 sudo i 创建一个文件夹来放置jdk解压后的文件 mkdir 文件夹mv jdk1.9(你下载的jdk文件) 你创建 的文...

无极之岚
25分钟前
1
0
程序中设置MySQL的默认值

import com.alibaba.fastjson.JSON;import java.beans.PropertyDescriptor;import java.lang.annotation.*;import java.lang.reflect.Field;import java.lang.reflect.Method;impo......

laolin23
49分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部