Ionic 2/3:同时数据绑定到提供者,并使用表单验证

时间:2017-04-13 16:33:15

标签: angular ionic2

我的应用程序中有一些绑定到提供程序的数据绑定,但现在我想添加一些表单验证。问题是当我开始尝试将[(ngModel)]与表单验证一起使用时出现错误。

我收到的错误消息表明:

  

ngModel不能用于向父级注册表单控件   formGroup指令。尝试使用             而是formGroup的合作伙伴指令\“formControlName \”。例如:

    <div [formGroup]=\"myGroup\">
      <input formControlName=\"firstName\">
    </div>

    In your class:

    this.myGroup = new FormGroup({
       firstName: new FormControl()
    });

      Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:

      Example:


    <div [formGroup]=\"myGroup\">
       <input formControlName=\"firstName\">
       <input [(ngModel)]=\"showMoreControls\" [ngModelOptions]=\"{standalone: true}\">
    </div>

如果我将其设置为独立([ngModelOptions]=\"{standalone: true}),那么我开始收到错误(Template parse errors: Can't bind to 'ngModelOptions' since it isn't a known property of 'ion-input'.),但除此之外,似乎表单验证可能也不起作用。另一方面,如果我删除了ngModel,那么数据就不再绑定到我的提供者了。

这是我的代码的一个非常简化的版本:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CaseProvider } from '../../providers/caseProvider';

@Component({
  selector: 'page-form',
  template: `
<ion-header>
</ion-header>

<ion-content>
    <div [formGroup]="myFormGroup">
        <ion-item>
            <ion-label>Record number</ion-label>
            <ion-input formControlName="record" [(ngModel)]="caseProvider.record"></ion-input>
        </ion-item>

        <button ion-button block (click)="saveCase()">
            <span>Save</span>
        </button>

    </div>
</ion-content>
  `
})
export class MyPage {

  myFormGroup: FormGroup;

  constructor(public formBuilder: FormBuilder, public caseProvider:CaseProvider) {
    this.myFormGroup = formBuilder.group({
        record: ['', Validators.compose([Validators.maxLength(30), Validators.pattern('.*[0-9].*')])]
    });
  }
  saveCase(){
   //save code here
  }
}

如何获取数据绑定到提供程序(其中包含getter和setter),并同时使用formGroup进行验证?

谢谢!

2 个答案:

答案 0 :(得分:2)

您不需要使用ngModel,因为您使用的是被动表单,因此您将值存储在表单控件中,并在提交后可以传递表单创建的完整对象并使用值。

所以删除ngModel,当你提交表单时,你在一个对象中整齐地拥有值,在你的情况下,它看起来像这样:

{
  record: 'whatever data'
}

因此,当您提交时,请传递saveCase方法中的表单值:

(click)="saveCase(myFormGroup.value)"

您将获得表单中的所有值。

Demo

在您的情况下,如果您想直接访问此表单控件,可以使用:

console.log(this.myFormGroup.controls.record.value);

您可以使用valueChanges订阅表单更改,如下所示:

this.myFormGroup.valueChanges.subscribe(data => {
  console.log(data); // here is whole object
})

<强>更新

如果您拥有caseProvider的界面(或类),则可以构建表单以使其与您的模型匹配。所以在这种情况下,如果你的界面看起来像这样:

export interface CaseProvider {
  record: string
}

并在您的TS文件中声明该变量:

caseProvider: CaseProvider;

由于您已经构建了表单,以便从表单中获取的对象与您的界面匹配,因此您可以直接在valueChanges中分配值,因为您说您需要不断更新它:

this.myFormGroup.valueChanges.subscribe(data => {
  this.caseProvider = data;
})

答案 1 :(得分:0)

我发现了更多关于Angular表单(https://angular.io/docs/ts/latest/guide/forms.html)而不是Ionic的文档(因为Ionic 2使用了Angular,但是Ionic在这里缺少一些文档),最终得到了以下允许使用ngModel和表单的解决方案验证:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CaseProvider } from '../../providers/caseProvider';

@Component({
  selector: 'page-form',
  template: `
<ion-header>
</ion-header>

<ion-content>
    <form #caseForm="ngForm" (ngSubmit)="saveCase(caseForm)">
        <ion-item>
            <ion-label>Record number</ion-label>
            <ion-input #record="ngModel" [(ngModel)]="caseProvider.record" maxlength="30" pattern=".*[0-9].*"></ion-input>
        </ion-item>
        <ion-item [hidden]="record.valid || record.pristine">
            Please enter a valid record number.
        </ion-item>

        <button type="submit" ion-button block [disabled]="!caseForm.form.valid">
             <span>Save</span>
        </button>

    </form>
</ion-content>
  `
})
export class Page2 {

  constructor(public formBuilder: FormBuilder, public caseProvider:CaseProvider) {

  }
  saveCase(form){
      if(form.valid){
        //save code here
      }{
        console.log('form is not valid');
      }
  }
}