angular6的响应式表单的实现


Posted in Javascript onOctober 10, 2018

1:在AppModule模块里面引入 ReactiveFormsModule

要使用响应式表单,就要从@angular/forms包中导入ReactiveFormsModule,并把它添加到你的NgModule的imports数组中。

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
 imports: [
 // other imports ...
 ReactiveFormsModule
 ],
})
export class AppModule { }

2:创建一个新的组件

ng g c NameEditor

3:请在组件中导入 FormControl 类

FormControl类是angular响应式表单最基本的构造快,要注册单个的表单控件,请在组件中导入FormControl类,并创建一个FormControl的新实例,把它保存在某个属性里面。

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
 selector: 'app-name-editor',
 templateUrl: './name-editor.component.html',
 styleUrls: ['./name-editor.component.css']
})

export class NameEditorComponent {
 name = new FormControl('');
}

4:在组件的模板中注册一个表单控件

修改模板,为表单控件添加 formControl 绑定,formControl 是由 ReactiveFormsModule 中的 FormControlDirective 提供的。

<label>
 Name:
 <input type="text" [formControl]="name">
</label>

<p>
 Value: {{ name.value }}
</p>

使用这种模板绑定语法,把该表单控件注册给了模板中名为 name 的输入元素。这样,表单控件和 DOM
元素就可以互相通讯了:视图会反映模型的变化,模型也会反映视图中的变化。

5:替换表单控件的值

FormControl 提供了一个setValue()方法,他会修改这个表单控件的值。

js

updateName() {
  this.name.setValue('Nancy');
 }

html

<label>
 Name:
 <input type="text" [formControl]="name">
</label>
<p>
 Value:{{name.value}}
</p>
<p>
 <button (click)="updateName()">Update Name</button>
</p>

在这个例子中,你只使用单个控件FormControl,但是当调用 FormGroup 或 FormArray 的 setValue()方法时,传入的值就必须匹配控件组或控件数组的结构才行

6:把表单控件分组

FormControl的实例能控制单个输入框所对应的控件,FormGroup可以控制一组FormControl实例的表单状态,当创建FormGroup时,其中的每一个控件都会根据名字进行跟踪

1>:创建新的组件

ng g c ProfileEditor

2>:导入 FormGroup 和 FormControl 类并且创建 FormGroup实例

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
 
@Component({
 selector: 'app-profile-editor',
 templateUrl: './profile-editor.component.html',
 styleUrls: ['./profile-editor.component.css']
})

export class ProfileEditorComponent {
 profileForm = new FormGroup({
 firstName: new FormControl(''),
 lastName: new FormControl(''),
 });
}

现在这些单独的控件FormControl被收集到了一个控件组中FormGroup, FormGroup 实例拥有和 FormControl 实例相同的属性(比如 value、untouched)和方法(比如 setValue())。

3>:关联FormGroup的模型和视图

FormGroup能追踪每个单独控件FormControl的状态和变化,如果其中某个控件的状态或值变化了,父控件也会一次新的状态变更或值变更事件

<form [formGroup]="profileForm">
 
 <label>
 First Name:
 <input type="text" formControlName="firstName">
 </label>

 <label>
 Last Name:
 <input type="text" formControlName="lastName">
 </label>

</form>

profileForm通过[formGroup]指令绑定到了 form元素,在该模型和表单中的输入框之间创建了一个通讯层,FormControlName 指令提供的 formControlName 属性把每个输入框和 FormGroup 中定义的表单控件绑定起来。

4>:关联FormGroup的模型和视图

html

<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
  <label>
  First Name:
  </label>
  <input type="text" formControlName="firstName">
 
  <label>
  Last Name:
  </label>
  <input type="text" formControlName="lastName">
 
  <button type="submit" >Submit</button>
 </form>

js

onSubmit () {
 console.warn(this.profileForm.value);
}

form 标签所发出的 submit 事件是原生 DOM 事件,通过点击类型为 submit 的按钮可以触发本事件

6:嵌套的表单组

js

profileForm = new FormGroup({
 firstName: new FormControl(''),
 lastName: new FormControl(''),
 address: new FormGroup({
  street: new FormControl(''),
  city: new FormControl(''),
  state: new FormControl(''),
  zip: new FormControl('')
 })
});

html

<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
 <label>
 First Name:
 </label>
 <input type="text" formControlName="firstName">
 <label>
 Last Name:
 </label>
 <input type="text" formControlName="lastName">

 <div formGroupName="address">
 <label>Streel</label>
 <input type="text" formControlName="street">
 <label>City</label>
 <input type="text" formControlName="city">
 <label>State</label>
 <input type="text" formControlName="state">
 <label>Zip Code</label>
 <input type="text" formControlName="zip">
 </div>

 <button type="submit" [disabled]="!profileForm.valid">Submit</button>
</form>

部分模型修改

html

<button (click)="updateProfile()">Update Profile</button>

js

updateProfile() {
  this.profileForm.patchValue({
  firstName: 'Nancy',
  address: {
   street: '123 Drew Street'
  }
  });
}

patchValue() 方法要针对模型的结构进行更新。patchValue() 只会更新表单模型中所定义的那些属性。

6:使用 FormBuilder 来生成表单控件

FormBuilder 服务提供了一些便捷方法来生成表单控件。

FormBuilder在幕后也使用同样的方式来创建和返回这些实例,只是用起来更简单。 下面会重构 ProfileEditor 组件,用FormBuilder 来代替手工创建这些 FormControl 和 FormGroup。

Step 1 - 导入 FormBuilder 类

import { FormBuilder } from '@angular/forms';

Step 2 - 注入FormBuild 服务

constructor(private fb: FormBuilder) { }

Step 3- 生成表单控件

FormBuilder 服务有三个方法:control()、group() 和 array()。这些方法都是工厂方法,用于在组件类中分别生成
FormControl、FormGroup 和 FormArray。

你可以使用 group() 方法,用和前面一样的名字来定义这些属性。这里,每个控件名对应的值都是一个数组,这个数组中的第一项是其初始值。你可以只使用初始值来定义控件,但是如果你的控件还需要同步或异步验证器,那就在这个数组中的第二项和

第三项提供同步和异步验证器。

import { Component } from '@angular/core';
import { FormBuilder } from '@angular/forms';
 
@Component({
 selector: 'app-profile-editor',
 templateUrl: './profile-editor.component.html',
 styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
 profileForm = this.fb.group({
 firstName: ['张'],
 lastName: ['娉'],
 address: this.fb.group({
  street: [''],
  city: [''],
  state: [''],
  zip: ['']
 }),
 });
 
 constructor(private fb: FormBuilder) { }
}

7:简单的表单验证

如何把单个验证器添加到表单控件中,以及如何显示表单的整体状态。

Step 1 - 导入验证器函数

import { Validators } from '@angular/forms';

响应式表单包含了一组开箱即用的常用验证器函数。这些函数接收一个控件,用以验证并根据验证结果返回一个错误对象或空值。

Step 2 - 把字段设为必填

最常见的校验项是把一个字段设为必填项。本节描述如何为 firstName 控件添加“必填项”验证器。

在组件中,把静态方法 Validators.required 设置为 firstName 控件值数组中的第二项。

profileForm = this.fb.group({
 firstName: ['', Validators.required],
 lastName: [''],
 address: this.fb.group({
 street: [''],
 city: [''],
 state: [''],
 zip: ['']
 }),
});

HTML5 有一组内置的属性,用来进行原生验证,包括 required、minlength、maxlength等。虽然是可选的,不过你也可以在表单的输入元素上把它们添加为附加属性来使用它们。这里我们把 required 属性添加到 firstName输入元素上。

<input type="text" formControlName="firstName" required>

这些 HTML5 验证器属性可以和 Angular响应式表单提供的内置验证器组合使用。组合使用这两种验证器实践,可以防止在模板检查完之后表达式再次被修改导致的错误。

8:显示表单的状态

现在,你已经往表单控件上添加了一个必填字段,它的初始值是无效的(invalid)。这种无效状态冒泡到其父 FormGroup 中,也让这个 FormGroup 的状态变为无效的。你可以通过该 FormGroup 实例的 status 属性来访问其当前状态。

<p>
 Form Status: {{ profileForm.status }}
</p>

9:使用表单数组管理动态控件

FormArray 是 FormGroup 之外的另一个选择,用于管理任意数量的匿名控件,如果你事先不知道子控件的数量,FormArray是一个很好的选择

Step 1 - 导入 FormArray

import { FormArray } from '@angular/forms';

Step 2 - 定义 FormArray

为 profileForm 添加一个 aliases 属性,把它定义为 FormArray 类型。(FormBuilder 服务用于创建 FormArray 实例。)

profileForm = this.fb.group({
 firstName: ['张', Validators.required],
 lastName: ['以'],
 address: this.fb.group({
  street: [''],
  city: [''],
  state: [''],
  zip: ['']
 }),
 aliases: this.fb.array([
  this.fb.control('')
 ])
 });

Step 3 - 访问FormArray控件

通过 getter 来访问控件比较便捷,也容易复用

使用 getter 语法来创建一个名为 aliases 的类属性

get aliases() {
 
}

从父控件 FormGroup 中接收绰号的 FormArray 控件。

get aliases() {
 return this.profileForm.get('aliases') as FormArray;
}
addAlias() {
 this.aliases.push(this.fb.control(''));
}

Step 3 - 在模板中显示表单数组

在模型中定义了 aliases 的 FormArray 之后,你必须把它加入到模板中供用户输入,使用 formArrayName 在这个
FormArray 和模板之间建立绑定。

<div formArrayName="aliases">
 <h3>Aliases</h3> <button (click)="addAlias()">Add Alias</button>

 <div *ngFor="let address of aliases.controls; let i=index">
 <!-- The repeated alias template -->
 <label>
  Alias:
  <input type="text" [formControlName]="i">
 </label>
 </div>
</div>

每当新的 alias 加进来时,FormArray 就会基于这个索引号提供它的控件。这将允许你在每次计算根控件的状态和值时跟踪每个控件。

全部代码

html

<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
 <label>
 First Name:
 </label>
 <input type="text" formControlName="firstName" required>

 <label>
 Last Name:
 </label>
 <input type="text" formControlName="lastName">

 <div formGroupName="address">
 <h3>Address</h3>
 <label>Streel</label>
 <input type="text" formControlName="street">

 <label>City</label>
 <input type="text" formControlName="city">
 
 <label>State</label>
 <input type="text" formControlName="state">

 <label>Zip Code</label>
 <input type="text" formControlName="zip">
 </div>

 <div formArrayName="aliases">
 <h3>Aliases</h3>
 <button (click)="addAlias()">Add Alias</button>
 
 <div *ngFor="let address of aliases.controls; let i=index">
  <label>Alias</label>
  <input type="text" [formControlName]="i" >
 </div>
 </div>

 <button type="submit" [disabled]="!profileForm.valid">Submit</button>
 <p>
 <button (click)="updateProfile()">Update Profile</button>
 </p>

 <p>
 Form Status: {{ profileForm.status }}
 </p>
</form>

js

import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup, FormBuilder, Validators, FormArray} from '@angular/forms';

@Component({
 selector: 'app-profile-editor',
 templateUrl: './profile-editor.component.html',
 styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent implements OnInit {
 profileForm = this.fb.group({
 firstName: ['张', Validators.required],
 lastName: ['以'],
 address: this.fb.group({
  street: [''],
  city: [''],
  state: [''],
  zip: ['']
 }),
 aliases: this.fb.array([
  this.fb.control('')
 ])
 });
 constructor(private fb: FormBuilder) {

 }

 ngOnInit() {
 }

 onSubmit () {
 console.warn(this.profileForm.value);
 }
 
 updateProfile() {
 this.profileForm.patchValue({
  firstName: 'Nancy',
  address: {
  street: '123 Drew Street'
  }
 });
 }
 get aliases () {
 return this.profileForm.get('aliases') as FormArray;
 }
 addAlias() {
 this.aliases.push(this.fb.control(''));
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 变量作用域 代码分析
Jun 26 Javascript
jQuery prev ~ siblings选择器使用介绍
Aug 09 Javascript
Array 重排序方法和操作方法的简单实例
Jan 24 Javascript
JS模拟酷狗音乐播放器收缩折叠关闭效果代码
Oct 29 Javascript
javascript实现dom元素可拖动
Mar 21 Javascript
基于Bootstrap使用jQuery实现简单可编辑表格
May 04 Javascript
深入浅析JavaScript中的Function类型
Jul 09 Javascript
Bootstrap登陆注册页面开发教程
Jul 12 Javascript
微信小程序 教程之WXSS
Oct 18 Javascript
underscore之Collections_动力节点Java学院整理
Jul 10 Javascript
JS中使用media实现响应式布局
Aug 04 Javascript
详解vue指令与$nextTick 操作DOM的不同之处
Aug 02 Javascript
JS原生带缩略图的图片切换效果
Oct 10 #Javascript
js实现前面自动补全位数的方法
Oct 10 #Javascript
Egg.js 中 AJax 上传文件获取参数的方法
Oct 10 #Javascript
轻量级富文本编辑器wangEditor结合vue使用方法示例
Oct 10 #Javascript
解决eclipse中没有js代码提示的问题
Oct 10 #Javascript
js实现同一个页面,多个enter事件绑定的示例
Oct 10 #Javascript
在React项目中使用Eslint代码检查工具及常见问题
Oct 10 #Javascript
You might like
Phpbean路由转发的php代码
2008/01/10 PHP
JS 遮照层实现代码
2010/03/31 Javascript
基于jQuery试卷自动排版系统
2010/07/18 Javascript
JS中confirm,alert,prompt函数区别分析
2011/01/17 Javascript
JS中令人发指的valueOf方法介绍
2013/02/22 Javascript
jQuery编辑器KindEditor4.1.4代码高亮显示设置教程
2013/03/01 Javascript
replace()方法查找字符使用示例
2013/10/28 Javascript
js获取url中指定参数值的示例代码
2013/12/14 Javascript
js捕获鼠标滚轮事件代码
2013/12/16 Javascript
JavaScript中调用函数的4种方式代码实例
2015/07/08 Javascript
BootStrap 动态表单效果
2017/06/02 Javascript
详解用webpack的CommonsChunkPlugin提取公共代码的3种方式
2017/11/09 Javascript
微信小程序实现tab切换效果
2017/11/21 Javascript
关于angularJs清除浏览器缓存的方法
2017/11/28 Javascript
vue单个组件实现无限层级多选菜单功能
2018/04/10 Javascript
解决layui中的form表单与button的点击事件冲突问题
2018/08/15 Javascript
浅谈Vue2.4.0 $attrs与inheritAttrs的具体使用
2020/03/08 Javascript
JavaScript实现拖拽效果
2020/03/16 Javascript
JS轮播图的实现方法2
2020/08/25 Javascript
vue-cli3项目打包后自动化部署到服务器的方法
2020/09/16 Javascript
python验证码识别教程之滑动验证码
2018/06/04 Python
用pycharm开发django项目示例代码
2018/10/24 Python
python 将json数据提取转化为txt的方法
2018/10/26 Python
Python字典的基本用法实例分析【创建、增加、获取、修改、删除】
2019/03/05 Python
python实现对输入的密文加密
2019/03/20 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
pytorch掉坑记录:model.eval的作用说明
2020/06/23 Python
Python爬虫Scrapy框架CrawlSpider原理及使用案例
2020/11/20 Python
加拿大奢华时装品牌:Mackage
2018/01/10 全球购物
ECCO英国官网:丹麦鞋履品牌
2019/09/03 全球购物
应用化学专业本科生求职信
2013/09/29 职场文书
校园达人秀策划书
2014/01/12 职场文书
团干部培训班心得体会
2016/01/06 职场文书
浙江省杭州市平均工资标准是多少?
2019/07/09 职场文书
JavaScript原始值与包装对象的详细介绍
2021/05/11 Javascript
Mysql binlog日志文件过大的解决
2021/10/05 MySQL