第五章 表单

表单是最重要也是最复杂的

表单可能是WEB世界里最重要的,通过表单获取用户的输入.另一方面,表单看起来又是简单的,你放置一个input标签,一个submit按钮,然后点击按钮,提交,有什么难的呢?

实践证明,表单确实是很复杂的,理由如下:

  • 表单输入意味着修改服务器与客户端的数据.
  • 改变通常会需要去反映到其他的地方
  • 用户会随意输入不同的值,所以需要校验
  • 如果需要,需要清楚地标明错误
  • 依赖字段具有复杂的逻辑
  • 不依靠DOM选择器,我们不能测试表单

幸运的是,angular2提供了解决这些问题的工具:

  • Controls封装了输入,并且提供一个与它们工作的对象
  • Validators给了我们一个校验工具
  • Observers让我们可以检测我们的表单,并且根据需要作出反应

在这一章,我们会深入学习表单.

Controls 和 Control Groups

ng2中,表单的两个基础设施就是Controls 和 Control Groups

Controls

Controls代表一个简单的输入域,它是ng2中表单的最小单元.

Controls封装了字段的值和有效,修改,错误的状态.

比如,我们会在Typescript中像下面一样使用Control

// create a new Control with the value "Nate"
let nameControl = new Control("Nate");

let name = nameControl.value; // -> Nate

// now we can query this control for certain values:
nameControl.errors // -> StringMap<string, any> of errors
nameControl.dirty // -> false
nameControl.valid // -> true
// etc.

为了构建表单,我们创建Control或者Control group,然后添加元数据和逻辑给它们.

像angular中的其他事情一样,我们有一个类(在本例子中是Control),我们会作为属性添加给DOM(本例子中是ngControl),如下:

<!-- part of some bigger form -->
<input type="text" ngControl="name" />

在我们的表单上下文中新建一个Control对象.

ControlGroup

许多表单都不止一个值,所以我们需要管理很多Controls,如果我们希望去校验我们的表单,去迭代每一个Control并校验是笨重的.为了解决这个问题,ControlGroup提供了一个封装.

下面我们创建一个ControlGroup.

let personInfo = new ControlGroup({
 firstName: new Control("Nate"),
 lastName: new Control("Murray"),
 zip: new Control("90210")
 })

ControlGroup和Control有一个公共的父类(AbstractControl).也就是说我们可以像一个简单Control一样检查personInfo的值和状态.

personInfo.value; // -> {
 // firstName: "Nate",
 // lastName: "Murray",
 // zip: "90210"
 //}

 // now we can query this control group for certain values, which have sensible
 // values depending on the children Control‘s values:
 personInfo.errors // -> StringMap<string, any> of errors
 personInfo.dirty // -> false
 personInfo.valid // -> true
 // etc.

注意,当我们获取ControlGroup的值时,我们会获取到一个key-value的对象.

第一个表单

这里有许多创建表单的重要方面我们没有提及,下面我们来逐一学习.

下面这个是我们将要创建的一个简单的表单:

在我们的理解中,我们创建一个电子商务型的网站,我们会列出我们出售的产品列表.在这个例子中,我们需要存储产品的SKU码,因此,我们创建一个获取SKU码的简单表单,它仅仅只有一个输入域.

我们的表单是非常简单的,它只有一个input和一个sumbit按钮.

让我们将这个表单组装成一个组件,如果你没有忘记,创建组件的三个部分为:

  • 配置
  • 创建模板
  • 实现组件类

Simple SKU,配置选项

code/forms/app/forms/demo_form_sku.ts

import { Component } from ‘@angular/core‘;
import { FORM_DIRECTIVES } from ‘@angular/common‘;
@Component({
  selector: ‘demo-form-sku‘,
  directives: [FORM_DIRECTIVES],

注意,这里我们导入了FORM_DIRECTIVES,FORM_DIRECTIVES是一个指令组,它包含:

  • ngControl
  • ngControlGroup
  • ngForm
  • ngModel

我们没有怎么使用这些指令,也没有说明它们能做什么.但是,现在,只需要知道我们需要使用这些指令就可以了.

Simple SKU模板

code/forms/app/ts/forms/demo_form_sku.ts

<div class="ui raised segment">
    <h2 class="ui header">Demo Form: Sku</h2>
    <form #f="ngForm" (ngSubmit)="onSubmit(f.value)" class="ui form">
      <div class="field">
        Forms in Angular 2 127
        <label for="skuInput">SKU</label>
        <input type="text" id="skuInput" placeholder="SKU" ngControl="sku">
        <button type="submit" class="ui button">Submit</button>
      </div>
    </form>
  </div>

form 和 NgForm

注意,我们导入了FORM_DIRECTIVES,所以我们可以使用ngForm添加到form上面.

NgForm做的事情是有好多好处的,而且也不明显.

导入FORM_DIRECTIVES后,ngForm会自动隐士地添加到任何的form标签上面.

ngForm给了我们两个东西:

  • 一个命名为ngForm的ControlGroup
  • 一个ngSubmit的输出

你可以在我们的代码中看到,我们使用了这两个东西:

<form #f="ngForm" (ngSubmit)="onSubmit(f.value)" class="ui form">
</form>

首先我们使用#f=”ngForm”创建了名为ngForm的表单,#v=thing说明,我们希望使用本地变量v代表这个view.

这里,我们创建了ngForm的标明,并绑定到变量f上.

我们的ngForm指令从哪里来? 它来自于NgForm指令.

ngForm的类型是什么?它是ControlGroup.这意味着我们可以将我们的视图作为ControlGroup使用.(ngSubmit)代表的是我们提交的时候需要做的事情.

所有添加起来的理解就是,当我们提交表单的时候,传递ControlGroup的value作为参数,调用我们组建的onSubmit方法.

input和ngControl

在我们讨论ngControl前,input标签有一些事情是我们感兴趣的.

code/forms/app/ts/forms/demo_form_sku.ts

<form #f="ngForm" (ngSubmit)="onSubmit(f.value)" class="ui form">
      <div class="field">
        Forms in Angular 2 127
        <label for="skuInput">SKU</label>
        <input type="text" id="skuInput" placeholder="SKU" ngControl="sku">
        <button type="submit" class="ui button">Submit</button>
      </div>
    </form>
  • class=”ui form”是可选的
  • for属性与input的id是对应的
  • placeholder是当用户没有输入的时候用来提示用的.

NgControl指令是用来标识ngControl这个选择器.这就意味着我们的input标签添加了这个属性:ngControl=”whatever”,这个例子中是sku.

NgControl会自动创建一个Control添加给父组件,这个例子中是ControlGroup.然后绑定这个DOM元素给Control.也就是说,我们通过名字sku将input与Control进行关联.

Simple SKU Form:组件定义

code/forms/app/ts/forms/demo_form_sku.ts

export class DemoFormSku { onSubmit(form: any): void {
    console.log(‘you submitted value:‘, form);
  }
}

试试

将所有代码合起来,像下面这样:

code/forms/app/ts/forms/demo_form_sku.ts

import { Component } from ‘@angular/core‘;
import { FORM_DIRECTIVES } from ‘@angular/common‘;

@Component({
  selector: ‘demo-form-sku‘,
  directives: [FORM_DIRECTIVES],
  template: `
  <div class="ui raised segment">
    <h2 class="ui header">Demo Form: Sku</h2>
    <form #f="ngForm"
          (ngSubmit)="onSubmit(f.value)"
          class="ui form">

      <div class="field">
        <label for="skuInput">SKU</label>
        <input type="text"
               id="skuInput"
               placeholder="SKU"
               ngControl="sku">
      </div>

      <button type="submit" class="ui button">Submit</button>
    </form>
  </div>
  `
})
export class DemoFormSku {
  onSubmit(form: any): void {
    console.log(‘you submitted value:‘, form);
  }
}

如果你运行这个程序,浏览器中会显示下面这样:

使用FormBuilder

隐式使用ngForm和ngControl是方便的,但是它没有给予我们太多的可自定义选项,通常,我们会使用一个更加复杂的方式创建form,那就是FormBuilder.

FormBuilder是一个帮助类,帮助我们创建表单.你可以将其理解为工厂方法.

让我们将FormBuilder添加到我们前面的例子中,看下面:

  • 在我们组件定义类中怎么使用FormBuilder
  • 是view中怎么使用自定义的ControlGroup.

怎么使用FormBuilder

在我们的组件类构造器参数中注入一个参数.

code/forms/app/ts/forms/demo_form_sku_with_builder.ts

export class DemoFormSkuBuilder { myForm: ControlGroup;
  constructor(fb: FormBuilder) {
    this.myForm = fb.group({
    ‘sku‘: [‘ABC123‘] });
}
onSubmit(value: string): void {
    console.log(‘you submitted value: ‘, value);
}

注入之后,一个FormBuilder的实例将会被创建,并且我们将其分配给局部变量fb.

我们将会使用FormBuilder的两个主要方法:

  • control:创建一个新的Control
  • group: 创建一个新的ControlGroup

注意,我们在本例子中使用myForm局部变量代表我们的表单.

myForm的类型是ControlGroup.通过fb.group创建的.group的参数是一个key-value,它代表这个ControlGroup里面的Control.在这个例子中,我们设置了一个名字为sku的Control,它的值是ABC123.

现在,我们有一个myForm的ControlGroup,我们需要使用它(通过绑定它到我们的form元素).

在view中使用myForm

我们希望改变去使用我们的myForm.如果没有忘记,在上面,我们说,导入FORM_DIRECTIVES时,ngForm会自动应用到我们的form元素上.我们也注意到了,ngForm创建了它自己的ControlGroup.好了,在这个例子中,我们不希望使用外部的ControlGroup,我们希望使用我们自己定义的myForm.我们应该怎么做?

当我们需要使用我们自己的ControlGroup时,angular提供了另外一种方式:它叫着ngFormModel,并且我们可以像下面这样使用它:

code/forms/app/ts/forms/demo_form_sku_with_builder.ts

 <form [ngFormModel]="myForm"
          (ngSubmit)="onSubmit(myForm.value)"

这里,我们使用ngFormModel告诉angular,我们将会使用myForm到这个上.

我们需要使用myForm的onSubmit代替f的onSubmit,最后一件事情就是绑定我们的Control到input上,使用NgFormControl.

code/forms/app/ts/forms/demo_form_sku_with_builder.ts

<input
type="text"
id="skuInput"
placeholder="SKU"
[ngFormControl]="myForm.controls[‘sku‘]">

试试

所有代码:

code/forms/app/ts/forms/demo_form_sku_with_builder.ts

import { Component } from ‘@angular/core‘;
import {
  FORM_DIRECTIVES,
  FormBuilder,
  ControlGroup
} from ‘@angular/common‘;

@Component({
  selector: ‘demo-form-sku-builder‘,
  directives: [FORM_DIRECTIVES],
  template: `
  <div class="ui raised segment">
    <h2 class="ui header">Demo Form: Sku with Builder</h2>
    <form [ngFormModel]="myForm"
          (ngSubmit)="onSubmit(myForm.value)"
          class="ui form">

      <div class="field">
        <label for="skuInput">SKU</label>
        <input type="text"
               id="skuInput"
               placeholder="SKU"
               [ngFormControl]="myForm.controls[‘sku‘]">
      </div>

    <button type="submit" class="ui button">Submit</button>
    </form>
  </div>
  `
})
export class DemoFormSkuBuilder {
  myForm: ControlGroup;

  constructor(fb: FormBuilder) {
    this.myForm = fb.group({
      ‘sku‘: [‘ABC123‘]
    });
  }

  onSubmit(value: string): void {
    console.log(‘you submitted value: ‘, value);
  }
}

记住:

隐式创建ControlGroup和Control使用:

- ngForm

- ngControl

绑定存在的ControlGroup和Control使用:

- ngFormModel

- ngFormControl

添加校验器

用户经常不会按正确的模式输入正确的数据,如果用户没有按正确的格式输入数据,我们可以给用户一个反馈,并且让其不能提交,这种情况下,我们使用校验器(Validators).

Validators被Validators模块提供,而且,最简单的Validators是Validators.required.

Validators.require标明该Control是必填字段.

为了使用Validators,我们必须做两件事情.

  • 分配一个Validator给Control
  • 检查Validator状态,并给出反馈
let control = new Control(‘sku‘, Validators.required);

在我们的例子中,由于使用了FormBuilder,所以可以像下面这样:

code/forms/app/ts/forms/demo_form_with_validations_explicit.ts

constructor(fb: FormBuilder) {
    this.myForm = fb.group({
      ‘sku‘:  [‘‘, Validators.required]

现在,我们需要使用Validators到我们的view上,在View上,有两种方式访问Validators.

  • 我们可以明确分配一个Control sku到我们类的实例,这个是比较啰嗦的,但是更加灵活.
  • 在view中,我们从myForm获取Control sku,这中方式,在Component类中的代码量少,但是在view中的代码多.

为了分析他们的区别,我们看下面的例子.

显示的将Control变量设置为实例变量

如下:

更加灵活的方式是将Controls分开成单独的Control放在组件类中,下面是我们的类代码:

code/forms/app/ts/forms/demo_form_with_validations_explicit.ts

export class DemoFormWithValidationsExplicit {
  myForm: ControlGroup;
  sku: AbstractControl;

  constructor(fb: FormBuilder) {
    this.myForm = fb.group({
      ‘sku‘:  [‘‘, Validators.required]
    });

    this.sku = this.myForm.controls[‘sku‘];
  }

  onSubmit(value: string): void {
    console.log(‘you submitted value: ‘, value);
  }
}

注意:

  • 我们在类中定义sku: AbstractControl
  • 当使用FormBuilder创建之后,我们分配给sku.

这是一个很好的注意,它表明我们可以在我们的view的任何地方使用sku.现在,我们的sku是可以被validated.我们希望找到不同的方式去使用它.

  • 校验所有的form,提供一条信息
  • 分开校验每一个Control,并提供一条信息
  • 分开校验每一个Control,当不合法的时候使用红色标注
  • 分开校验每一个Control,是否已经输入,如果没有输入,显示一条信息

表单信息

我们可以通过检查myForm.valid来校验myForm.

code/forms/app/ts/forms/demo_form_with_validations_explicit.ts

<div *ngIf="!myForm.valid"

字段信息

我们也可以在字段不符合规定的时候显示一条信息

code/forms/app/ts/forms/demo_form_with_validations_explicit.ts

[ngFormControl]="sku">
         <div *ngIf="!sku.valid"

字段颜色

我们也可以标注字段的颜色,当不合法的时候.

code/forms/app/ts/forms/demo_form_with_validations_explicit.ts

<div class="field"
          [class.error]="!sku.valid && sku.touched">

指定特定的校验器

当需要依靠特定的校验器时,也可以制定.通过hasError()来实现.

code/forms/app/ts/forms/demo_form_with_validations_explicit.ts

class="ui error message">SKU is invalid</div>
<div *ngIf="sku.hasError(‘required‘)"

所有代码

code/forms/app/ts/forms/demo_form_with_validations_explicit.ts

/* tslint:disable:no-string-literal */
import { Component } from ‘@angular/core‘;
import {
  CORE_DIRECTIVES,
  FORM_DIRECTIVES,
  FormBuilder,
  ControlGroup,
  Validators,
  AbstractControl
} from ‘@angular/common‘;

@Component({
  selector: ‘demo-form-with-validations-explicit‘,
  directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
  template: `
  <div class="ui raised segment">
    <h2 class="ui header">Demo Form: with validations (explicit)</h2>
    <form [ngFormModel]="myForm"
          (ngSubmit)="onSubmit(myForm.value)"
          class="ui form">

      <div class="field"
          [class.error]="!sku.valid && sku.touched">
        <label for="skuInput">SKU</label>
        <input type="text"
               id="skuInput"
               placeholder="SKU"
               [ngFormControl]="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>
  `
})
export class DemoFormWithValidationsExplicit {
  myForm: ControlGroup;
  sku: AbstractControl;

  constructor(fb: FormBuilder) {
    this.myForm = fb.group({
      ‘sku‘:  [‘‘, Validators.required]
    });

    this.sku = this.myForm.controls[‘sku‘];
  }

  onSubmit(value: string): void {
    console.log(‘you submitted value: ‘, value);
  }
}

显示设置sku Controls作为组件类的实例变量

像我们上面一样,我们在组件类中创建了一个实例变量存储每一个input标签.

但是我们能不能不创建实例变量而直接浏览Control呢?答案是肯定的.我们会学习浏览Form的其他方式.

让我们看看另外的例子.

code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts

export class DemoFormWithValidationsShorthand {
    myForm: ControlGroup;
      constructor(fb: FormBuilder) {
            this.myForm = fb.group({
                ‘sku‘: [‘‘, Validators.required] });
      }
      onSubmit(value: any): void {
        console.log(‘you submitted value:‘, value.sku);
      }
}

这两个例子的代码有点像,但是仔细看,你会发现,sku: AbstractControl已经不在这里面了.

让我们看看这三个字段级别的校验器,跟上面的作为对比.

声明一个本地sku引用

因为我们没有直接定义一个本地变量保存sku引用,所以我们需要一种获得它引用的方式,这里有两种方式:

  • 通过myForm.find
  • 通过ngFormControl

myForm.find

myForm具有一个find函数,它可以通过路径找到它的子元素,然后校验他们.

code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts

<div class="field"
      [class.error]="!myForm.find(‘sku‘).valid && myForm.find(‘sku‘).touched">

这比前面的代码还多,不可取.

通过NgFormControl导出

这里有另外一种方式获得引用,**通过ngForm导出ngFormControl.这是前面章节没有讲过的内容.

Component可以导出他们自己的引用,让你可以在视图中引用它们

我们在接下来的章节中讲解怎么使用exportAs导出,但是现在只需要知道,很多内建组件都可以像这样做.

在这个例子中,NgFormControl导出它自己作为ngForm.你可以使用#reference来引用他们.

如下:

code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts

<input
type="text"
id="skuInput"
placeholder="SKU"
#sku="ngForm"
[ngFormControl]="myForm.controls[‘sku‘]">

注意,上面的就是使用ngFormControl导出它自己引入变量sku,但是要注意,sku是一个指令,不是Control.为了访问sku Control,需要使用sku.control.

现在,sku对于我们来说是可以利用的.我们可以像下面这样使用它.

code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts

<div *ngIf="!sku.control.valid"
class="ui error message">SKU is invalid</div>
<div *ngIf="sku.control.hasError(‘required‘)" class="ui error message">SKU is required</div>

sku变量的范围

当我们创建一个引用的时候,它是可以在其兄弟节点或者子节点使用,但是不能在其父节点使用.

比如,不能像下面这样:

// this won‘t work
   <div class="field"
[class.error]="!sku.control.valid && sku.control.touched">

因为div是form的父元素.

全部代码

code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts

import { Component } from ‘@angular/core‘;
import {
  CORE_DIRECTIVES,
  FORM_DIRECTIVES,
  FormBuilder,
  ControlGroup,
  Validators
} from ‘@angular/common‘;

@Component({
  selector: ‘demo-form-with-validations-shorthand‘,
  directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
  template: `
<div class="ui raised segment">
  <h2 class="ui header">Demo Form: with validations (shorthand)</h2>
  <form [ngFormModel]="myForm"
        (ngSubmit)="onSubmit(myForm.value)"
        class="ui form">

    <div class="field"
      [class.error]="!myForm.find(‘sku‘).valid && myForm.find(‘sku‘).touched">
      <label for="skuInput">SKU</label>
      <input type="text"
             id="skuInput"
             placeholder="SKU"
             #sku="ngForm"
             [ngFormControl]="myForm.controls[‘sku‘]">
       <div *ngIf="!sku.control.valid"
         class="ui error message">SKU is invalid</div>
       <div *ngIf="sku.control.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>
  `
})
export class DemoFormWithValidationsShorthand {
  myForm: ControlGroup;

  constructor(fb: FormBuilder) {
    this.myForm = fb.group({
      ‘sku‘:  [‘‘, Validators.required]
    });
  }

  onSubmit(value: any): void {
    console.log(‘you submitted value:‘, value.sku);
  }
}

自定义校验器

我们通常需要编写自己的校验器,怎么做?

为了弄清楚怎么实现自定义校验器,让我们看看内建的Validators.required.

export class Validators {
  static required(c: Control): StringMap<string, boolean> {
    return isBlank(c.value) || c.value == "" ? {"required": true} : null;
}

输入为一个Control,输出为一个

编写一个校验器

比如我们希望标志我们的sku,输入的必须是以123开头的.

我可以像下面这样写:

code/forms/app/ts/forms/demo_form_with_custom_validations.ts

function skuValidator(control: Control): { [s: string]: boolean } { if (!control.value.match(/^123/)) {
    return {invalidSku: true};
  }
}

当输入的不是以123开头时,这个校验器会返回invalidSku的错误代码.

分配校验器给Control

现在我们需要将skuValidator添加到Control上面去.但是这里有一个问题,我们的sku上面已经有一个校验器了,我们怎么添加多个校验器到同一个Control呢?

答案是我们使用Validators.compose.如下:

code/forms/app/ts/forms/demo_form_with_custom_validations.ts

this.myForm = fb.group({
      ‘sku‘:  [‘‘, Validators.compose([
        Validators.required, skuValidator])]
    });

Validators.compose包装多个校验器给Control,当所有的校验器都是有效的时候,Control才是有效的.否则校验不通过.

现在我们可以在视图中使用这个新的校验器.

code/forms/app/ts/forms/demo_form_with_custom_validations.ts

<div *ngIf="sku.hasError(‘invalidSku‘)"
class="ui error message">SKU must begin with <tt>123</tt></div>

监听变化

到现在为止,当表单提交的时候,我们只是从我们的表单中读取数据.但是通常,我们希望监听每一个Control的变化.

ControlGroup与Control都有一个EventEmitter,它可以用来监听数据的变化.

为了监听变化,我们需要做下面的两个操作:

  • 通过调用control.valueChanges获取
  • 使用EventEmitter.observer方法添加一个观察者

下面是一个例子:

code/forms/app/ts/forms/demo_form_with_events.ts

export class DemoFormWithEvents {
  myForm: ControlGroup;
  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);
  }
}

这里我们监听两个事件:sku变化事件和整个form的变化事件.

我们传递进去的是一个简单的key.接下来是一个函数,当值变哈的时候会被调用.

ngModel

ngModel是一个特殊的指令,它绑定一个Model给form.ngModel是一个实现了双向数据绑定的特殊指令.双向数据绑定是比较复杂的.angular2默认使用的是单项数据流,但是在Form中,由于需要跟踪用户改变,所以使用双向数据绑定.

看下面的例子:

code/forms/app/ts/forms/demo_form_ng_model.ts

export class DemoFormNgModel {
    myForm: ControlGroup; productName: string;
    constructor(fb: FormBuilder) {
        this.myForm = fb.group({
        ‘productName‘: [‘‘, Validators.required] });
    }
    onSubmit(value: string): void {
        console.log(‘you submitted value: ‘, value);
    }
}

注意,我们在勒种定义了productName: string 实例变量.然后让我们看看在input标签中怎么使用ngModel:

code/forms/app/ts/forms/demo_form_ng_model.ts

<input
    type="text"
    id="productNameInput"
    placeholder="Product Name"
    [ngFormControl]="myForm.find(‘productName‘)"
    [(ngModel)]="productName">   

ngModel的语法是很奇特的,它使用[]和()合起来,由前面的可知,[]是输入,()是输出,也就是说双向就是输入和输出都绑定了.

然后,我们将productName显示出来.

code/forms/app/ts/forms/demo_form_ng_model.ts

<div class="ui info message">
The product name is: {{productName}}
</div>

看起来像下面这样:

可以看到,是实时同步的.

总结

Form有很多的复杂功能,但是angular2提供了一个清晰明了的方式,一旦你学会使用了ControlGroups, Controls, 和 Validations,使用表单就会变得很简单了.

时间: 2024-10-20 21:05:21

第五章 表单的相关文章

Django学习笔记(五)—— 表单

疯狂的暑假学习之  Django学习笔记(五)-- 表单 参考:<The Django Book> 第7章 1. HttpRequest对象的信息 request.path                                 除域名以外的请求路径,斜杠开头                      "/hello/" request.get_host()                      主机名                              

第10章 表单元素(上)

第10章表单元素[上] 学习要点:1.表单元素总汇2.表单元素解析 本章主要探讨 HTML5中表单元素,表单元素用于获取用户的输入数据.一.表单元素总汇在 HTML5的表单中,提供了各种可供用户输入的表单控件.元素名称 说明form 表示 HTML表单input 表示用来收集用户输入数据的控件textarea 表示可以输入多行文本的控件select 表示用来提供一组固定的选项option 表示提供提供一个选项optgroup 表示一组相关的 option元素button 表示可用来提交或重置的表

javascript高级程序设计 第十四章--表单脚本

javascript高级程序设计 第十四章--表单脚本 在HTML中表单由<form>元素表示,在js中表单对应的是HTMLFormElement类型,这个类型也有很多属性和方法:取得表单元素的引用还是为它添加id特性,用DOM操作来获取表单元素:提交表单:把<input>或<button>元素的type特性设置为"submit",图像按钮把<input>元素的type特性设置为"image",也可以调用submit(

玩转web之json(五)---将表单通过serialize()方法获取的值转成json

form表单有一个serialize()方法,可以序列化表单的值,但是jquery提供的这个方法会把数据序列化为类似下面的形式: a=1&b=2&c=3&d=4 jquery并没有提供将表单数据序列化为json的方法,所以需要我们自己封装一下,下面给出代码和测试样例,先写一个js文件: $.ajaxSetup({ contentType: "application/x-www-form-urlencoded; charset=utf-8" }); var Dat

第10章 表单元素(中)

第 10章表单元素[中]学习要点:1.type属性总汇2.type属性解析 本章主要探讨 HTML5中表单中 input元素的 type属性,根据不同的值来显示不同的输入框.一.type属性总汇input元素可以用来生成一个供用户输入数据的简单文本框.在默认的情况下,什么样的数据均可以输入.而通过不同的属性值,可以限制输入的内容. 属性名称 说明text 一个单行文本框,默认行为password 隐藏字符的密码框search 搜索框,在某些浏览器键入内容会出现叉标记取消submit.reset.

ASP.NET MVC5 高级编程 第5章 表单和HTML辅助方法

参考资料<ASP.NET MVC5 高级编程>第5版 第5章 表单和HTML辅助方法 5.1 表单的使用 5.1.1 action 和 method 特性 默认情况下,表单发送的是 HTTP Post 请求 EF 对于外键关系,数据库名称等也有约定.这些约定取代了以前需要提供给一个关系对象映射框架的所有映射和配置. GET 方法:GET 请求的所有参数都在URL中,因此可以为GET 请求建立书签. POST 方法:浏览器把输入值放入 HTTP 请求的主体中. 5.2 辅助方法 可以通过视图的H

JavaScript高级程序设计第14章表单脚本 (学习笔记)

第十四章 表单脚本 1.阻止默认表单提交 1.提交表单数据 1.使用type=submit提交按钮 2.使用submit():方法 注意:当用户点击提交按钮时,会触发submit事件,从而在这里我们有机会验证数据并决定要不要提交表单 1.preventnDefault(event):可以用在表单数据无效时不发给服务器,对于动态绑定的onclick 事件. 2.Submit()方法也可以提交表单,但是不会触发submit事件,所以在使用时须先验证表单数据, 如:<%response.write(t

第三章 表单笔记

第三章                                                                表单  笔记 attion 此属性指示服务器处理表单输出的程序一般来说,当用户单点击的"提交"按钮后信息发送到Web服务器上,由attion属性所指的程序处理如果action为空则默认提交到本页method此属性告诉浏览器,如何将数据发送给服务器,他指向服务器发送数据的方法.语法为method=(getpost)<form method="

第 10 章 表单元素[下]

学习要点: 1.其他元素 2.输入验证 主讲教师:李炎恢 本章主要探讨 HTML5 中表单中剩余的其他元素,然后重点了解一下表单的输入验证功能. 一.其他元素 表单元素还剩下几个元素没有讲解,包括下拉框列表 select.多行文本框 textarea.和 output 计算结果元素. 元素名称 说明 select 生成一个下拉列表进行选择 optgroup 对 select 元素进行编组 option select 元素中的项目 textarea 生成一个多行文本框 output 表示计算结果