表单

来源:互联网 发布:中锐网络经营范围 编辑:程序博客网 时间:2024/05/21 18:49

一、在这章中,我们将学会

1、使用组件和模板构建一个Angular表单

2、使用ngModel语法实现双向绑定,以便于读取和写入输入控件的值。

3、结合表单来使用ngModel,能让我们跟踪状态变化并对表单控件作出验证,

4、使用特殊的css类来跟踪状态,并提供强烈的视觉反馈。

5、向用户显示有效性验证的错误提示,以及禁用、启用表单控件

6、通过模板引用变量,在控件中共享信息。


二、模板驱动的表单

我们大多数都可以表单特有的指令本章描述的技术,在模板中按照Angular模板语法来构建表单。

创建该表单的步骤:

1、创建Hero模型类

2、创建控制此表单的组件

3、创建具有初始表单布局的模板

4、使用ngModel双向绑定语法把数据属性绑定到每个表单输入控件中

5、往每个表单输入控件添加name属性

6、添加自定义css来提供视觉反馈

7、显示和隐藏自定义有效性验证信息

8、使用ngSubmit处理表单提交

9、禁用表单的提交按钮,直至表单变为有效


三、创建一个Hero模型类

export class Hero {  constructor(    public id: number,    public name: string,    public power: string,    public alterEgo?: string  ) {  }}


四、创建一个表单组件

import { Component } from '@angular/core';import { Hero }    from './hero';@Component({  moduleId: module.id,  selector: 'hero-form',  templateUrl: 'hero-form.component.html'})export class HeroFormComponent {  powers = ['Really Smart', 'Super Flexible',            'Super Hot', 'Weather Changer'];  model = new Hero(18, 'Dr IQ', this.powers[0], 'Chuck Overstreet');  submitted = false;  onSubmit() { this.submitted = true; }  // TODO: Remove this when we're done  get diagnostic() { return JSON.stringify(this.model); }}

1、从Angular库中导入@Component装饰器

2、导入刚刚创建的Hero模型

3、@Component选择器hero-form表示我们可以通过一个<hero-form>标签把此表单扔到父模板中。

4、moduleId属性设置了已相对于模块的路径加载templuateUrl的时使用的基地址。

5、templuateUrl指向了一个独立的Url模板


五、修改app.module.ts

1、app.module.ts定义了应用的根模块,在那里我们指出了即将用到的外部模块,并且声明了属于本模块的组件,比如HeroFormComponent。

因为模板驱动的表单有他们自己的模块,所以我们必须把FormsModule添加到本应用的import数组中,这样我们才能使用表单

import { NgModule }      from '@angular/core';import { BrowserModule } from '@angular/platform-browser';import { FormsModule }   from '@angular/forms';import { AppComponent }  from './app.component';import { HeroFormComponent } from './hero-form.component';@NgModule({  imports: [    BrowserModule,    FormsModule  ],  declarations: [    AppComponent,    HeroFormComponent  ],  bootstrap: [ AppComponent ]})export class AppModule { }

如果有一个组件、指令或者管道出现在模块的import数组中,就说明他是外来模块,不要再到declarations中声明他,如果是你自己写的,并且属于当前模块,就把他加到declarations中


六、修改app.component.ts

app.component.ts是本应用的根组件,我们把HeroFormComponent放在其中

import { Component } from '@angular/core';@Component({  selector: 'my-app',  template: '<hero-form></hero-form>'})export class AppComponent { }


七、创建一个初始HTML表单模板

<div class="container">    <h1>Hero Form</h1>    <form>      <div class="form-group">        <label for="name">Name</label>        <input type="text" class="form-control" id="name" required>      </div>      <div class="form-group">        <label for="alterEgo">Alter Ego</label>        <input type="text" class="form-control" id="alterEgo">      </div>      <button type="submit" class="btn btn-default">Submit</button>    </form></div>


八、用ngFor添加超能力

在Alter Ego下方添加以下HTML

<div class="form-group">  <label for="power">Hero Power</label>  <select class="form-control" id="power" required>    <option *ngFor="let p of powers" [value]="p">{{p}}</option>  </select></div>


九、使用ngModel进行双向数据绑定

找到Name对应的input标签

<input type="text"  class="form-control" id="name"       required       [(ngModel)]="model.name" name="name">  TODO: remove this: {{model.name}}


注意:我们往<input>标签上添加一个name属性,这表示英雄的名字,在表单中使用ngModel时,必须定义name属性

十、ngModel

[()]是很好的线索,在属性绑定中,一个值从模型中传到屏幕上的目标属性,我们通过[]完成模型到视图的单项数据绑定。在事件绑定中,我们通过()完成视图到模型的反向数据绑定。


十一、通过ngModel跟踪修改状态与有效性验证

在表单中使用ngModel不仅能够跟踪状态,他还能使用三个css类来更新控件,以便反应当前状态。我们可以通过定制这些css类样式来更改控件外观。

控件是否被访问过:ng-touched ng-untouched

控件值是否有变化: ng-dirty ng-pristine

控件值是否有效: ng-vaild ng-invalid


我们往<input>标签上添加一个名叫spy的临时变量,让我们能够看清楚上面的css类

<input type="text" class="form-control" id="name"  required  [(ngModel)]="model.name" name="name"  #spy ><br>TODO: remove this: {{spy.className}}


十一、显示和隐藏有效性验证的错误信息

Name框是必填的,清空他会让表单底部变红,我们可以通过以下方法来扩展input标签

下面是我们要做的

        <label for="name">Name</label>        <input type="text" class="form-control" id="name"               required               [(ngModel)]="model.name" name="name"ng               #name="ngModel" >        <div [hidden]="name.valid || name.pristine"              class="alert alert-danger">          Name is required        </div>

我们需要一个模板引用变量来访问模板中输入框的Angular控件,这里,我们创建了一个名叫name的变量,并把它赋值为ngModel。

为什么是ngModel?指令的exportAs属性告诉Angular如何把模板引用变量连接到指令中,这里我们把name设置为ngModel就是因为ngModel指令的exportAs属性设置为ngModel。

在这个范例中,当控件是全新或者有效时,我们要隐藏消息。


十二、添加英雄并且重置表单

我们希望在这个表单中添加一个新的英雄,

<button type="button" class="btn btn-default" (click)="newHero()">New Hero</button>

再次运行应用,点击新增按钮,表单被清空了,但是输入一个名字,并且再次点击新增按钮,我们却看到了错误信息,这是因为Angular没有办法区分这个操作是替换了整个英雄数据还是清空了name属性,因此,我们给组件添加了一个active标记,并把它初始化为true,当我们添加一个英雄时,他把active标记成false,然后通过一个快速的setTimeout函数把他设置回true.

  active = true;  newHero() {    this.model = new Hero(42, '', '');    this.active = false;    setTimeout(() => this.active = true, 0);  }

然后把form元素绑定到这个active元素上之后,点击新增英雄将从DOM中移除这个表单,并且很快重建他,重新创建的表单处于全新状态,错误信息就被隐藏了。


十三、通过ngSubmit来提交表单

在填表完成后,用户还应该能提交这个表单,他自己不会做任何事,但是因为具有特殊的type值submit,因此他会触发表单提交。

但是仅仅触发表单提交是没有用的,要让他有用,我们还有用另一个Angular指令更新Angular,NgSubmit,并且通过事件绑定机制把他绑定到HeroFormComponent.submit方法中。

<form *ngIf="active" (ngSubmit)="onSubmit()" #heroForm="ngForm">


我们定义了一个模板引用变量,#heroForm,并且把他初始化为ngForm,这个heroForm变量现在引用的是NgForm指令,他代表的是整个表单


Angular替我们自动创建了NgForm指令,并且把他附加到form标签上,NgForm指令为普通的form元素扩展了更多特性,他持有我们通过ngModel指令和name属性为各个元素创建的那些控件类,并且监视他们的属性变化,包括有效性,他还有自己的vaild属性,只有当每个属性都有效时,他才有效。

在之后的部分,通过heroForm变量,我们把按钮的disable属性绑定到了表单的全员有效性。




0 0