大佬教程收集整理的这篇文章主要介绍了Angular 2 + 折腾记 :(7) 初步了解表单:模板驱动及数据驱动及脱坑要点,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
表单在整个系统中的作用相当重要,这里主要扯下响应表单的实现方式。
首先需要操作表单的模块引入这两个模块;
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
模板驱动表单依赖FormsModule
,数据驱动的表单依赖FormsModule,ReactiveFormsModule
一般做表单校验及操作推荐用数据驱动的方式,好维护和理解。。
模板驱动:主要是依赖[(ngModel)]
和#scope_var
以及原生表单控件属性(require
,@H_453_6@minlenght,@H_453_6@maxlength等)来操作表单的那的值亦或者校验
<!--#UserName 是局部变量,若是有ngmodel,拿到的就是一个响应对象,若是非ngmodel绑定的,则是dom元素代码-->
<!--testform这个局部变量保存了表单的所有相关信息-->
<!--ngSubmit是用来触发表单提交的-->
<!--ngModel相应变量的值-->
<!--$event是原生dom对象-->
<form #testform="ngForm" (ngSubmit)="Submit(testform.value,testform.valid)">
<label for="username">Name</label>
<input type="text" id="username" #UserName="username" class="form-control" required @H_746_52@minlength="4" @H_746_52@maxlength="24" name="username" [(ngModel)]="username" [ngModelChange]="validate($event)">
<div *ngIf="UserName.valid || (UserName.prisTine && !testform.submitted)">
您输入的值有误,请重新输入
</div>
<button type="submit" >提交</button>
</form>
有两种方式处理来对上面的表单做校验;
Submit()
函数内,在点击提交的时候对整个表单一一去判断,传统方式基本这样[ngModelChange]
来处理双向绑定的值校验响应式表表单:原理是一开始就构建整个表单,表单的值通过特殊指令formControlName
一一关联(类似ngModel
);
相关名词:
- FormGroup
: 用来追踪表单控件有效状态及值 =》 可以理解为获取且可以操作整个表单的数据
- FormBuilder
:表单数据构建工具[构建初始表单],简化构建代码(包括了new FormGroup()
,new FormControl()
,new FormArray()
),FormGroup()
内置多种校验方式
- formControlName
: 同步与FormGroup
构建表单内相同字段的值!
项目中的案例
<div [@flyIn]="true">
<div class="beautify-form" *ngIf="!showLoading">
<div class="page-header">
欢迎登录
</div>
<form [formGroup]="form" (ngSubmit)="onSubmit(form)">
<div class="form-group" [ngClass]="{ 'has-danger': form.controls.username.invalid && form.controls.username.value,'has-success': form.controls.username.valid && form.controls.username.value }">
<div class="input-group input-group-lg">
<span class="input-group-addon fpd fpd-ordinarylogin1"></span>
<input type="text" class="form-control" formControlName="UserName" placeholder="手机号码 \ 邮箱 ">
</div>
<div class="form-control-FeedBACk" *ngIf="(form.controls.username.dirty || form.controls.username.prisTinE) && form.controls.username.invalid && form.controls.username.value">账号不符合规范</div>
<div class="form-control-FeedBACk" *ngIf="(form.controls.username.dirty || form.controls.username.prisTinE) && form.controls.username.valid && form.controls.username.value">账号符合规范</div>
</div>
<div class="form-group" [ngClass]="{ 'has-danger': form.controls.password.invalid && form.controls.password.value,'has-success': form.controls.password.valid && form.controls.password.value }">
<div class="input-group input-group-lg">
<span class="input-group-addon fpd fpd-mima"></span>
<input type="password" class="form-control" formControlName="password" placeholder="请输入密码">
</div>
<div class="form-control-FeedBACk" *ngIf="(form.controls.password.dirty || form.controls.password.prisTinE) && form.controls.password.invalid && form.controls.password.value ">密码不符合规范,请重新输入</div>
<div class="form-control-FeedBACk" *ngIf="(form.controls.password.dirty || form.controls.password.prisTinE) && form.controls.password.valid && form.controls.password.value ">密码符合规范</div>
</div>
<div class="form-group ">
<div class="flex">
<div class="beautify-wrap flex-wrap">
<input type="checkBox" class="beautify-checkBox" name="rememberme" id="rememberAccount" formControlName="rememberAccount">
<label for="rememberAccount"></label>记住账号
</div>
<!--<a [routerLink]="['/account/reset-pw']">忘记密码</a>-->
</div>
</div>
<div class="message-tips" *ngIf="messageTips">
<i class="fpd fpd-error"></i> {{messageTips}}
</div>
<div class="form-group ">
<button class="btn btn-lg btn-outline-success btn-block" type="submit" [disabled]="form.invalid">登录</button>
</div>
<div class="form-group">
<span class="noaccount-notify">没有账号?点击</span><a [routerLink]="['/account/collect']" class="collect-user">用户登记</a>
</div>
</form>
</div>
<div class="loading" *ngIf="showLoading">
<app-mit-loading [option]="'load4'"></app-mit-loading>
</div>
</div>
import { Component,OnInit,OnDestroy } from '@angular/core';
import { FormGroup,Validators,FormBuilder } from '@angular/forms'; // 引入表单的一些特性
import { Router } from '@angular/router';
import { Accountservice } from '../../services/account.service';
import { environment } from '../../../../../environments/environment';
import { flyIn } from '../../../../animation/flyIn';
import { Observable } from 'rxjs/Observable';
@Component({
SELEctor: 'app-login',templateUrl: './login.component.html',styleUrls: ['./login.component.scss'],animations: [flyIn]
})
export class LoginComponent implements OnInit,OnDestroy {
public form: FormGroup; // 表单对象
public showLoading = false;
public messageTips: String;
public login_subscribe: any;
// Validators的写法注意事项
// v2.x版本这样的写法是可行的,v4有调整,不然不会生效
// 'UserName':'',[ Validators.compose([Validators.minLength(6)]
// v4+,第一位的''代表这个元素初始化构建为空值,类似未输入状态
// 'UserName': ['',Validators.compose([Validators.minLength(6)]
// Validators可选参数
// 1. required :必须验证的,返回布尔值
// 2. minLength : 最小长度
// 3. maxLenght: 最大长度
// 4. nullValidator : 空值判断
// 5. coompose :多重判断组合,下面有写法
constructor(private fb: FormBuilder,private router: Router,private account: AccountservicE) {
this.form = fb.group({
'UserName': ['',Validators.compose([Validators.minLength(6) || Validators.pattern('(0|86|17951)?(-)?1[3,4,5,7,8,9]\\d{9}') || Validators.pattern('[\\.a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+')])],'password': ['',Validators.compose([Validators.required,Validators.pattern('\\w{8,16}')])],'rememberAccount': ['']
});
}
ngOnInit() {
}
// 登录事件
onSubmit(E) {
this.showLoading = true;
this.login_subscribe = this.account.login(e.value).subscribe((res) => {
console.log('省略。。。。。。')
},(err) => {
this.showLoading = false;
});
}
ngOnDestroy() {
if (this.login_subscribE) {
this.login_subscribe.unsubscribe();
}
}
}
效果图
有些时候我们接口数据层次不可能只有一层,出现两层三层都有可能;
这时候需要我们构建一个嵌套表单。。。
v2-的写法:表单的取值可以用controls
直接点出来
<div class="custom-card">
<div class="custom-card-body">
<form [formGroup]="form" (ngSubmit)="onSubmit(form.value)">
<div class="row" formGroupName="RuleContent">
<div class="col-sm-12 col-md-12 col-lg-8 offset-lg-2">
<div class="form-group row" [ngClass]="{ 'has-danger': form.controls.RuleContent.controls.Fencename.invalid && form.controls.RuleContent.controls.Fencename.value,'has-success': form.controls.RuleContent.controls.Fencename.valid && form.controls.RuleContent.controls.Fencename.value }">
<label tooltip="" class="col-sm-10 col-md-3 form-control-label col-lg-3 star">速度栅栏名称</label>
<div class="col-sm-8 col-md-6 col-lg-6">
<input type="text" class="form-control" formControlName="Fencename" placeholder="栅栏名称">
</div>
<div class="col-2 col-sm-4 col-lg-3 flex-align-center">
不超过十个字
</div>
</div>
<div class="form-group row" [ngClass]="{ 'has-danger': form.controls.RuleContent.controls.MaxSpeed.invalid && form.controls.RuleContent.controls.MaxSpeed.value,'has-success': form.controls.RuleContent.controls.MaxSpeed.valid && form.controls.RuleContent.controls.MaxSpeed.value }">
<label tooltip="" class="col-sm-10 col-md-3 form-control-label col-lg-3 star">速度阈值</label>
<div class="col-sm-8 col-md-6 col-lg-6">
<input type="number" class="form-control" @H_746_52@min="1" formControlName="MaxSpeed" placeholder="整数">
</div>
<div class="col-2 col-sm-4 col-lg-3 flex-align-center">
km/h
</div>
</div>
<div class="form-group row">
<div class="col-12 col-sm-10 col-md-6 offset-sm-2 offset-md-4 offset-lg-3">
<button type="submit" class="btn btn-priMary" [disabled]="form.invalid">保存</button>
<button type="button" class="btn btn-secondary" (click)="BACk()">取消</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
v4+的写法 :嵌套表单的取值必须用.get()
来获取,不然会报错误,具体原因是api改动了,看下官方文档就知道,改动了挺多(不仅仅这块)
<div class="custom-card">
<div class="custom-card-body">
<form [formGroup]="form" (ngSubmit)="onSubmit(form.value)">
<div class="row" formGroupName="RuleContent">
<div class="col-sm-12 col-md-12 col-lg-8 offset-lg-2">
<div class="form-group row" [ngClass]="{ 'has-danger': form.get('RuleContent.Fencename').invalid && form.get('RuleContent.Fencename').value,'has-success': form.get('RuleContent.Fencename').valid && form.get('RuleContent.Fencename').value }">
<label tooltip="" class="col-sm-10 col-md-3 form-control-label col-lg-3 star">速度栅栏名称</label>
<div class="col-sm-8 col-md-6 col-lg-6">
<input type="text" class="form-control" formControlName="Fencename" placeholder="栅栏名称">
</div>
<div class="col-2 col-sm-4 col-lg-3 flex-align-center">
不超过十个字
</div>
</div>
<div class="form-group row" [ngClass]="{ 'has-danger': form.get('RuleContent.MaxSpeed').invalid && form.get('RuleContent.MaxSpeed').value,'has-success': form.get('RuleContent.MaxSpeed').valid && form.get('RuleContent.MaxSpeed').value }">
<label tooltip="" class="col-sm-10 col-md-3 form-control-label col-lg-3 star">速度阈值</label>
<div class="col-sm-8 col-md-6 col-lg-6">
<input type="number" class="form-control" @H_746_52@min="1" formControlName="MaxSpeed" placeholder="整数">
</div>
<div class="col-2 col-sm-4 col-lg-3 flex-align-center">
km/h
</div>
</div>
<div class="form-group row">
<div class="col-12 col-sm-10 col-md-6 offset-sm-2 offset-md-4 offset-lg-3">
<button type="submit" class="btn btn-priMary" [disabled]="form.invalid">保存</button>
<button type="button" class="btn btn-secondary" (click)="BACk()">取消</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
import { Component,OnInit } from '@angular/core';
import { Router,ActivatedRoute } from '@angular/router';
import { FormGroup,FormControl,FormBuilder } from '@angular/forms'; // 引入表单的一些特性
// 动画
import { fadeIn } from '../../../../../animation/fadeIn';
// 服务
import { SpeedFenceservice } from '../speed-fence.service';
import { Eventsservice } from '../../../../../services/events-service.service';
@Component({
SELEctor: 'app-modify',templateUrl: './modify.component.html',styleUrls: ['./modify.component.scss'],animations: [fadeIn]
})
export class @H_880_50@modifyComponent implements OnInit {
public form: FormGroup;
public getId: any;
public id: number;
constructor(
private speedFenceservice: SpeedFenceservice,private eventsservice: Eventsservice,private router: Router,private activatedRoute: ActivatedRoute,private fb: FormBuilder
) {
this.form = fb.group({
'ID': 0,'RuleContent': this.fb.group({
'MaxSpeed': [0,Validators.pattern('(([4-9][0-9])|(1[0-1][0-9])|(120))')])],'Fencename': ['',Validators.minLength(2),Validators.maxLength(10)])],})
});
}
ngOnInit() {
this.checkAction();
// console.log(this.form);
}
// 获取ID
checkAction() {
this.activatedRoute.params.subscribe@H_740_1489@((params: { id: String }) => { console.log(params); if (params.id) { console.log(this.id); this.id = parseInt(params.id,10); this.form.controls['ID'].SETVALue(this.id); this.GetSpeedFenceSetTingByFencEID({ FencEID: parseInt(params.id,10) }); } }); } GetSpeedFenceSetTingByFencEID(data) { this.speedFenceservice.GetSpeedFenceSetTingByFencEID(data).subscribe( res => { if (res.StatE) { this.form.controls['RuleContent'].SETVALue({ 'MaxSpeed': res.Data.RuleContent.MaxSpeed || '','Fencename': res.Data.RuleContent.Fencename || '',}); } },err => { } ); } onSubmit(form) { console.log('此处省略。。。。。'); } // 取消 BACk() { if (this.id) { this.router.navigate(['../../'],{ relativeTo: this.activatedRoute }); } else { this.router.navigate(['../'],{ relativeTo: this.activatedRoute }); } } }
多看手册多动手,才是真理。。
以上是大佬教程为你收集整理的Angular 2 + 折腾记 :(7) 初步了解表单:模板驱动及数据驱动及脱坑要点全部内容,希望文章能够帮你解决Angular 2 + 折腾记 :(7) 初步了解表单:模板驱动及数据驱动及脱坑要点所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。