第九课:用户输入

不是所有的移动应用都要求用户输入,但是大部分都需要。在某些时候,我们需要搜集用户数据。可能是一些状态更新用到的文本,他们的名字和收货地址,搜索条件,他们待办列表的标题等等。
不管这些数据是什么,他都需要用户在模板中输入。为了明确起见,在Ionic 2中我们可以通过以下代码来创建一个表单:

  1. <ion-list>
  2. <ion-item>
  3. <ion-label>Username</ion-label>
  4. <ion-input type="text"></ion-input>
  5. </ion-item>
  6. <ion-item>
  7. <ion-label>Password</ion-label>
  8. <ion-input type="password"></ion-input>
  9. </ion-item>
  10. </ion-list>

以上代码会生成一个简单的登录表单,效果是这样的:
登录框

这个登录框允许用户在输入框内输入一些信息。但是,我们需要知道用户在我们的.html中输入了什么然后在.ts类中使用。本课中我们将讨论一些不同的达成方式。

双向数据绑定

如果你之前用过Ionic 1的话,那么你应该非常熟悉这个概念,如果没有的话,别担心,因为这个改变非常直白。双向数据绑定实际上就是将模板里的一个输入域和类里面的变量值链接起来。以下范例:
模板:

  1. <ion-input type="text" [(ngModel)]="myValue"></ion-input>

类:

  1. myValue: string;
  2. constructor(){
  3. }

如果我们改变模板里的,然后类定义里的 this.myValue 会被更新到这个值。如果我们改变类里面的 this.myValue ,模板里面对于的输入域会自动更新对应的值。通过 ngModel 将两个值绑在一起,一个改变的时候,另一个随之改变。
假设我们在模板里有一个提交按钮:

  1. <ion-input type="text" [(ngModel)]="myValue"></ion-input>
  2. <button ion-button (click)="logValue()">Log myValue!</button>

当用户点击按钮是时候我们将他们输入的值打印到控制台。由于按钮点击的时候会调用logValue函数,我们需要在类定义里面添加如下:

  1. logValue(){
  2. console.log(this.myValue);
  3. }

不管你在输入框里面输入了什么,这个函数都会拿到然后输出到控制台,当然你也可以用这些数据干更有意义的事情。这是一个非常方便的操作输入的方法,因为我们不需要去担心函数的传入值,我们直接去拿当前的值就可以了。
这在有大量的输入框的时候会显得有点笨拙,所以也不会永远是完美选择。当用于处理复杂表单的时候,我们还有另一个选择,现在就来看另一个选择。

Form Builder

Form Builder是Angular 2提佛那个的一个服务,可以用来更简单的处理表单。Form Builder可以做的事情不止这些,但是他最简单的目的是允许你同时管理大量输入域同时提供了更简单的方法来验证用户输入(例如,是否输入了有效的邮件地址)。
想要使用Form Builder的话,需要先导入(同时导入FormGroup)然后注入到你的构造器,如下:

  1. import { Component } from '@angular/core';
  2. import { NavController } from 'ionic-angular';
  3. import { FormBuilder, FormGroup, Validators } from '@angular/forms';
  4. @Component({
  5. templateUrl: 'my-details.html',
  6. })
  7. export class MyDetailsPage {
  8. constructor(public formBuilder: FormBuilder) {
  9. }
  10. }

请注意,此处也导入了Validators,用于与Form Builder验证用户输入。我们来快速了解一下如何使用Form Builder创建一个表单。这个方法最重要的不同是你的输入需要放到定义好了formGroup熟悉的

标签里:

  1. <form [formGroup]="myForm" (submit)="saveForm($event)">
  2. <ion-item>
  3. <ion-label stacked>Field 1</ion-label>
  4. <ion-input formControlName="field1" type="text"></ion-input>
  5. </ion-item>
  6. <ion-item>
  7. <ion-label stacked>Field 2</ion-label>
  8. <ion-input formControlName="field2" type="text"></ion-input>
  9. </ion-item>
  10. <ion-item>
  11. <ion-label stacked>Field 3</ion-label>
  12. <ion-input formControlName="field3" type="text"></ion-input>
  13. </ion-item>
  14. <button type="submit">Save Form</button>
  15. </form>

也许你注意到了在以上的范例中我们给每个输入域定义了formControlName属性,这就是我们现在用作Form Builder区分它们的方式。当然,我们需要一个提交表单的方法,所以我们添加了一个提交按钮同时在表单上添加了一个(submit)监听器用于调用saveForm函数。我们稍后定义这个函数,但是为了让所有这些能够正常工作,我们需要在页面的构造器函数里面初始化表单。大概是这样的:

  1. this.myForm = formBuilder.group({
  2. field1: [''],
  3. field2: [''],
  4. field3: ['']
  5. });

我们只要提交所有表单里面的域(使用我们定义的formControlName)然后给所有的域一个初始值(例子中我们使用的是空字符串)。你也可以给每个域提供第二个值来定义Validator,如:

  1. this.myForm = formBuilder.group({
  2. field1: ['', Validators.required],
  3. field2: ['', Validators.required],
  4. field3: ['']
  5. });

同时注意this.myForm变量必须和我们在模板中提供的 [formGroup]的值一样。现在来看一下 saveForm 函数:

  1. saveForm(event){
  2. event.preventDefault();
  3. console.log(this.myForm.value);
  4. }

我们传递submit事件然后调用preventDefault这样提交表单的默认行为不会发生,我们只想通过这个函数自己处理。我们可以轻松的通过的使用this.myForm.value获取用户在表单中的详细数据。

使用Form Builder设置数据稍微复杂些,但是更强大,对于更加复杂的表单值得去尝试。对于更加简单的需求,使用 [(ngModel)] 在大部分案例中更好。