模板式表单
表单数据模型通过组件模板中的相关指令定义,但是只适用于一些简单的场景。比较死板
指令:来自FormsModule模块中
在app.modules.ts中
import { FormsModule } from "@angular/forms";
@NgModule({
declarations: [
],
imports: [
FormsModule
],
})
ngForm 作用
1.ngForm指令可以发现所有标有 ‘ngModel’的子元素,并将其值添加到表单模型中 创建FormGroup的实例,将数据存储在ngForm.value对象中。
2.任何标有“ngForm”指令的元素都会有此作用。不论是不是form表单元素
3.当不希望Angular接管表单时,可给表单标签添加“ngNoForm”指令。
4.ngForm指令可以被模板本地变量引用,来访问模板表单的实例
5.会阻止表单的提交并刷新,使用**ngSubmit**事件来提交
6.隐式创建FormGroup类型的实例
ngModel 作用
1.ngModel是ngForm指令所在元素的子元素的字段,与name属性相关联(仅当添加name属性后才能被模板捕获,创建数据模型)。
2.会隐式创建FormControl的实例,来代表该字段,并用FormControl创建的对象存储其值。
3.ngModel代表一个字段,而不是双向绑定,不需要绑定变量,也不需要在组件中声明变量。
4.ngModel指令可以被模板本地变量引用,来访问模板表单的字段的值。
ngFormGroup 作用:
1.与ngForm类似,也会创建FormGroup的实例,该数据是嵌套在ngForm.value对象中的。
2.用来将有联系的表单元素放置于一块,并组成对象格式数据。
示例:
在app.module.ts导入FormsModule:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from "@angular/forms";
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
@NgModule({
declarations: [
AppComponent,
HeaderComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
在app.component.html:
<h1>
{{ msg }}
h1>
<form #myForm="ngForm" (ngSubmit)="createUser(myForm.value)">
<div>姓名:<input type="text" #myName="ngModel" ngModel name="myname">div>
<div>邮箱:<input type="email" ngModel name="email">div>
<div>手机号:<input type="number" ngModel name="mobile">div>
<div ngModelGroup="passwordInfo">
<div>密码:<input type="password" ngModel name="password">div>
<div>确认密码:<input type="password" ngModel name="passwordConfirm">div>
div>
<button tyoe="submit">注册button>
form>
<div>
{{myForm.value | json}}
div>
<div>
{{myName.value | json}}
div>
<router-outlet>router-outlet>
在app.component.ts中:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
#myForm="ngForm"
msg = '欢迎来到码上加油站';
createUser(info: any) {
console.log(info);
}
}
运行项目:
响应式表单
通过typescript创建底层的数据模型。可通过特定的指令将模板上的HTML元素和底层的数据模型相联系。比较灵活。
表单指令:
编写步骤:
(1)用代码编写数据模型
(2)将数据模型与HTML页面ngModel相连接
数据模型:
用来保存表单数据的数据结构,简称模型。
由FormsModule中的三个类组成:FormControl、FormGroup、FormArray.
FormControl指代form中的单个字段
FormGroup指代form中的所有字段或者有关联的字段,类型为对象,可嵌套
FormArray指代form中可能有多个值的字段,类型为数组
示例:
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
@NgModule({
declarations: [
AppComponent,
HeaderComponent
],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
在app.component.html:
<h1>
{{ msg }}
h1>
<form [formGroup]="formModel" (submit)="createUser()">
<div>姓名:<input type="text" formControlName="nickname">div>
<div>邮箱:
<ul formArrayName="emails">
<li *ngFor="let email of formModel.get('emails')['controls'];let i = index;">
<input [formControlName]="i">
li>
ul>
<button tyoe="button" (click)="addEmail()">增加emailbutton>
div>
<div>手机号:<input type="number" formControlName="mobile">div>
<div formGroupName="passwordInfo">
<div>密码:<input type="password" formControlName="password">div>
<div>确认密码:<input type="password" formControlName="passwordConfirm">div>
div>
<button tyoe="submit">注册button>
form>
<router-outlet>router-outlet>
在app.component.ts中:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
formModel: FormGroup;
fb: FormBuilder = new FormBuilder();
msg = "码上加油站"
constructor() {
this.formModel = new FormGroup({ // 整个表单是FormGroup类型的数据
nickname: new FormControl(), // 昵称为FormControl类型的数据
mobile: new FormControl(),
emails: new FormArray([ // 数组
new FormControl('a@a.com'),
new FormControl('b@b.com')
]),
passwordInfo: new FormGroup({ // 密码是FormGroup类型的数据,被嵌套在FormGroup中
password: new FormControl(),
passwordConfirm: new FormControl()
})
});
}
ngOnInit(): void {
}
addEmail() {
let emails = this.formModel.get('emails') as FormArray;
emails.push(new FormControl());
console.log(this.formModel.value);
}
createUser() {
console.log(this.formModel.value);
}
}
也可以写成:
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
formModel: FormGroup;
fb: FormBuilder = new FormBuilder();
msg = "码上加油站"
constructor() {
this.formModel = this.fb.group({
nickname: ['hello'],
mobile: [''],
emails: this.fb.array([
['a@a.com'],
['b@b.com']
]),
passwordInfo: this.fb.group({
password: [''],
passwordConfirm: ['']
})
});
// this.formModel = new FormGroup({ // 整个表单是FormGroup类型的数据
// nickname: new FormControl(), // 昵称为FormControl类型的数据
// mobile: new FormControl(),
// emails: new FormArray([ // 数组
// new FormControl('a@a.com'),
// new FormControl('b@b.com')
// ]),
// passwordInfo: new FormGroup({ // 密码是FormGroup类型的数据,被嵌套在FormGroup中
// password: new FormControl(),
// passwordConfirm: new FormControl()
// })
// });
}
ngOnInit(): void {
}
addEmail() {
let emails = this.formModel.get('emails') as FormArray;
emails.push(new FormControl());
console.log(this.formModel.value);
}
createUser() {
console.log(this.formModel.value);
}
}
运行项目:
两种表单的区别
1.都需要数据模型来存储表单数据。
2.数据模型由angular/forms模块中的一些特定的类,如FormControl,FormGroup等组成。
3.模板式表单中,数据模型由组件模板中的指令隐式创建。响应式表单中,数据模型自己来创建,并与HTML元素相连接。
4.模板式表单中,不能访问这些类;而响应式可以。
5.模板式表单只需引入FormsModule模块
6.使用响应式,必须引入 FormsModule、 ReactiveFormsModule这两个模块。
完
码上加油站
一起来加油
长按扫码关注
![e0ee1bfdd5647c2c42f8db3def4831ca.png](https://img-blog.csdnimg.cn/img_convert/e0ee1bfdd5647c2c42f8db3def4831ca.png)