美文网首页
angular4-03 forms

angular4-03 forms

作者: 漫漫江雪 | 来源:发表于2017-07-24 18:12 被阅读0次

1、新建项目
ng new forms

Paste_Image.png
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

  1. 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:

  1. Assign a validator to the FormControl object
  2. 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);
  }
}

相关文章

网友评论

      本文标题:angular4-03 forms

      本文链接:https://www.haomeiwen.com/subject/crvdkxtx.html