1、新建项目
ng new forms
cd forms
cnpm install
ng serve --open
2、要使用angular的表单,需要在NgModule中引入FormsModule或者ReactiveFormsModule
FormsModule用于 ngModel和NgForm
ReactiveFormsModule用于 formControl和ngFormGroup
当使用了FormsModule,NgForm会自动附加到视图上的form表单上,NgForm会默认包含以下两点:
1)一个名为ngForm的 FormGroup
- A (ngSubmit) Output
import {FormsModule,ReactiveFormsModule} from '@angular/forms';
@NgModule({
declarations: [
FormsDemoApp,
DemoFormSkuComponent,
// ... our declarations here
],
imports: [
BrowserModule,
FormsModule, // <-- add this
ReactiveFormsModule // <-- and this
],
bootstrap: [ FormsDemoApp ]
})
class FormsDemoAppModule {}
在.angular-cli.json文件中加入一个全局样式
"styles": [
"assets/vendor/semantic.min.css",
"styles.css"
],
3、因为有多个form表单的例子,这里加上angular的路由,同样在app.module.ts下增加路由
import {RouterModule,Routes} from '@angular/router';
//...
import { AppComponent } from './app.component';
import { IntroComponent } from './intro/intro.component';
import { DemoFormSkuComponent } from './demo-form-sku/demo-form-sku.component';
const routes:Routes=[
{path:'',component:IntroComponent,pathMatch:'full'},
{path:'sku',component:DemoFormSkuComponent,pathMatch:'full'}
];
@NgModule({
declarations: [
AppComponent,
IntroComponent,
DemoFormSkuComponent
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
接着改写根组件的html,加上路由的router-outlet,即app.component.html文件
<div class="ui menu">
<div class="ui container">
<a href="#" class="header item">
![](/assets/images/ng-book-2-minibook.png)
</a>
<div class="header item borderless">
<h1 class="ui header">Angular Forms</h1>
</div>
</div>
</div>
<div class="ui stackable grid container">
<div class="six wide column">
<app-sidebar [items]="examples"></app-sidebar>
</div>
<div class="ui main text container ten wide column">
<router-outlet></router-outlet>
</div>
</div>
4、创建组件intro.component.ts和demo-form-sku.component.ts组件
ng g component intro
ng g component demo-form-sku
5、修改组件 demo-form-sku.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-demo-form-sku',
templateUrl: './demo-form-sku.component.html',
styleUrls: ['./demo-form-sku.component.css']
})
export class DemoFormSkuComponent implements OnInit {
constructor() { }
ngOnInit() {
}
onSubmit(form:any):void{
console.log('you submitted value:',form);
}
}
demo-form-sku.component.html
<div class="ui raised segment">
<h2 class="ui header">Demo Form:Sku</h2>
<!--
#f="ngForm"写法是定义一个视图的本地变量 即给 ngForm取个别名f
-->
<form #f="ngForm" (ngSubmit)="onSubmit(f.value)" class="ui form">
<div class="field">
<label for="skuInput">SKU</label>
<!--
单单使用ngModel表示是单向绑定
ngModel代表会创建一个FormControl,如下name是sku
-->
<input type="text" id="skuInput" name="sku" placeholder="SKU" ngModel>
</div>
<button type="submit" class="ui button">Submit</button>
</form>
</div>
6、Using FormBuilder ng g component component demo-form-sku-with-builder
import { Component, OnInit } from '@angular/core';
import {FormBuilder,FormGroup} from '@angular/forms';
@Component({
selector: 'app-demo-form-sku-with-builder',
templateUrl: './demo-form-sku-with-builder.component.html',
styleUrls: ['./demo-form-sku-with-builder.component.css']
})
export class DemoFormSkuWithBuilderComponent implements OnInit {
myForm:FormGroup;
constructor(fb:FormBuilder) {
this.myForm=fb.group({
'sku':['ABC123']
})
}
ngOnInit() {
}
onSubmit(value:string):void{
console.log('you submitted value:'+value);
}
}
demo-form-sku-with-builder.component.html
<div class="ui raised segment">
<h2 class="ui header">Demo Form:Sku with Builder</h2>
<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)" class="ui form">
<div class="field">
<label for="skuInput">SKU</label>
<input type="text" id="skuInput" name="sku" placeholder="SKU" [formControl]="myForm.controls['sku']">
</div>
<button type="submit" class="ui button">Submit</button>
</form>
</div>
备注:表单中使用了 [formGroup],如 <form [formGroup]="myForm" ....>之后,则不再会自动产生名为ngForm的FormGroup
也就是用FormBuilder时,表单中使用formGroup,就不会有默认的ngForm了
当要显示的产生 FormGroup和FormControl时 使用 ngForm和ngModel
当要把已经存在的FormGroup (如FormBuilder生成的)绑定到View使用 formGroup和formControl
7、表单验证
要使用angular的validator
首先要在FormControl上设置验证规则
其次检测视图上FormControl设置的验证器状态,对各状态作相应的响应处理
(To use validators we need to do two things:
- Assign a validator to the FormControl object
- Check the status of the validator in the view and take action accordingly)
添加组件ng g component demo-form-with-validations-explicit
import { Component } from '@angular/core';
import {FormBuilder,FormGroup,Validators,AbstractControl} from '@angular/forms';
@Component({
selector: 'app-demo-form-with-validations-explicit',
templateUrl: './demo-form-with-validations-explicit.component.html'
})
export class DemoFormWithValidationsExplicitComponent {
myForm:FormGroup;
sku:AbstractControl;
constructor(fb:FormBuilder) {
this.myForm=fb.group({
'sku':['',Validators.required]
});
this.sku=this.myForm.controls['sku'];
}
onSubmit(value: any): void {
console.log('you submitted value: ', value);
}
}
demo-form-with-validations-explicit.component.html
<div class="ui raised segment">
<h2 class="ui header">Demo Form:with validations (explicit)</h2>
<form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form" [class.error]="!myForm.valid && myForm.touched">
<div class="field">
<label for="skuInput">SKU</label>
<input type="text" id="skuInput" placeholder="SKU" [formControl]="sku" />
<div *ngIf="!sku.valid" class="ui error message">SKU is invalid</div>
<div *ngIf="sku.hasError('required')" class="ui error message">SKU is required</div>
</div>
<div *ngIf="!myForm.valid" class="ui error message">Form is invalid</div>
<button type="submit" class="ui button">Submit</button>
</form>
</div>
8、自定义验证
以 sku需以123开头为例,参考 validators.required的定义:
export class Validators {
static required(c: FormControl): StringMap<string, boolean> {
return isBlank(c.value) || c.value == "" ? {"required": true} : null;
}
function skuValidator(control: FormControl): { [s: string]: boolean } {
if (!control.value.match(/^123/)) {
return {invalidSku: true};
}
}
demo-form-with-custom-validation.component.ts
import { Component } from '@angular/core';
import {FormBuilder,FormGroup,Validators,AbstractControl,FormControl} from '@angular/forms';
function skuValidator(control:FormControl):{[s:string]:boolean}{
if(!control.value.match(/^123/)){ //验证是否以123开头
return {invalidSku:true};
}
}
@Component({
selector: 'app-demo-form-with-custom-validation',
templateUrl: './demo-form-with-custom-validation.component.html'
})
export class DemoFormWithCustomValidationComponent {
myForm:FormGroup;
sku:AbstractControl;
constructor(fb:FormBuilder) {
this.myForm=fb.group({
'sku':['',Validators.compose([Validators.required,skuValidator])]
})
this.sku=this.myForm.controls['sku'];
}
onSubmit(value:string):void{
console.log('you submitted value:',value);
}
}
demo-form-with-custom-validation.component.html
<div class="ui raised segment">
<h2 class="ui header">Demo Form:with validations (explicit)</h2>
<form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form" [class.error]="!myForm.valid && myForm.touched">
<div class="field">
<label for="skuInput">SKU</label>
<input type="text" id="skuInput" placeholder="SKU" [formControl]="sku" />
<div *ngIf="!sku.valid" class="ui error message">SKU is invalid</div>
<div *ngIf="sku.hasError('required')" class="ui error message">SKU is required</div>
<div *ngIf="sku.hasError('invalidSku')" class="ui error message">SKU格式不正确,以123开头</div>
</div>
<div *ngIf="!myForm.valid" class="ui error message">Form is invalid</div>
<button type="submit" class="ui button">Submit</button>
</form>
</div>
9、跟踪数据变化 demo-form-with-events.component.ts
import { Component } from '@angular/core';
import {FormBuilder,FormGroup,Validators,AbstractControl} from '@angular/forms';
@Component({
selector: 'app-demo-form-with-events',
templateUrl: './demo-form-with-events.component.html'
})
export class DemoFormWithEventsComponent {
myForm:FormGroup;
sku:AbstractControl;
constructor(fb:FormBuilder) {
this.myForm=fb.group({
'sku':['',Validators.required]
});
this.sku=this.myForm.controls['sku'];
this.sku.valueChanges.subscribe((value:string)=>{
console.log('sku changed to:',value);
});
this.myForm.valueChanges.subscribe((form:any)=>{
console.log('form changed to:',form);
});
}
onSubmit(form: any): void {
console.log('you submitted value:', form.sku);
}
}
网友评论