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 相关文章推荐
IE6/7 and IE8/9/10(IE7模式)依次隐藏具有absolute或relative的父元素和子元素后再显示父元素
Jul 31 Javascript
ASP.NET jQuery 实例12 通过使用jQuery validation插件简单实现用户注册页面验证功能
Feb 03 Javascript
jQuery提交表单ajax查询实例代码
Oct 07 Javascript
你必须知道的Javascript知识点之&quot;字面量和对应类型&quot;说明介绍
Apr 23 Javascript
JSON无限折叠菜单编写实例
Dec 16 Javascript
原生javascript实现图片弹窗交互效果
Jan 12 Javascript
Json解析的方法小结
Jun 22 Javascript
bootstrap网格系统使用方法解析
Jan 13 Javascript
基于JavaScript实现弹幕特效
Aug 27 Javascript
Vue的MVVM实现方法
Aug 16 Javascript
node文字生成图片的示例代码
Oct 26 Javascript
利用Promise自定义一个GET请求的函数示例代码
Mar 20 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
深入PHP数据加密详解
2013/06/18 PHP
php实现给图片加灰色半透明效果的方法
2014/10/20 PHP
PHP速成大法
2015/01/30 PHP
php通过array_merge()函数合并两个数组的方法
2015/03/18 PHP
使用tp框架和SQL语句查询数据表中的某字段包含某值
2019/10/18 PHP
JS获取月的最后一天与JS得到一个月份最大天数的实例代码
2013/12/16 Javascript
javascript教程:关于if简写语句优化的方法
2014/05/17 Javascript
node.js中的path.sep方法使用说明
2014/12/08 Javascript
JS实现支持多选的遍历下拉列表代码
2015/08/20 Javascript
jQuery轻松实现表格的隔行变色和点击行变色的实例代码
2016/05/09 Javascript
怎么限制input的text里输入的值只能是数字(正则、js)
2016/05/16 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
Jquery循环截取字符串的方法(多出的字符串处理成&quot;...&quot;)
2016/11/28 Javascript
浅谈Vue数据绑定的原理
2018/01/08 Javascript
nodejs制作小爬虫功能示例
2020/02/24 NodeJs
Jquery如何使用animation动画效果改变背景色的代码
2020/07/20 jQuery
python实现html转ubb代码(html2ubb)
2014/07/03 Python
python采用requests库模拟登录和抓取数据的简单示例
2014/07/05 Python
Python爬虫获取整个站点中的所有外部链接代码示例
2017/12/26 Python
Windows下PyCharm安装图文教程
2018/08/27 Python
Python判断一个文件夹内哪些文件是图片的实例
2018/12/07 Python
详解Python3中setuptools、Pip安装教程
2019/06/18 Python
jupyter notebook读取/导出文件/图片实例
2020/04/16 Python
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
2019/06/03 HTML / CSS
实例讲解使用HTML5 Canvas绘制阴影效果的方法
2016/03/25 HTML / CSS
加拿大专业美发产品购物网站:Chatters
2021/02/28 全球购物
求职简历自荐信范文
2013/10/21 职场文书
岗位职责范本
2013/11/23 职场文书
关于毕业的广播稿
2014/01/10 职场文书
应届电子商务毕业自荐书范文
2014/02/11 职场文书
加油口号大全
2014/06/13 职场文书
员工试用期自我评价
2014/09/18 职场文书
办公室文员工作自我鉴定
2014/09/19 职场文书
个人年度总结报告
2015/03/09 职场文书
起诉状范本
2015/05/20 职场文书
JavaScript高级程序设计之变量与作用域
2021/11/17 Javascript