【问题标题】:Ionic 2/3: simultanously data binding to a provider, and using form validationIonic 2/3:同时将数据绑定到提供者,并使用表单验证
【发布时间】:2017-04-20 02:40:22
【问题描述】:

我的应用程序中有一些数据绑定,它们绑定到提供程序,但现在我想添加一些表单验证。问题是当我开始尝试将[(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 进行验证?

谢谢!

【问题讨论】:

  • 你可以将它绑定到你的formControl,这是你应该做的。因此,当您构建表单(或使用patchValue)时,请在构建表单时设置formControlName ...例如firstName:[showMoreControls, Validators.required]或您拥有的任何东西:)
  • 你能展示你的htmlts你的组件代码吗?
  • 我已经更新了我的问题以显示我的一些代码。
  • @AJT_82 你是说有一种方法可以从表单组中绑定吗?看起来您的示例将第一个参数作为应该绑定的变量传递?我以为表单控件中传递的第一个参数是表单状态?
  • 如果你有caseProvider.record中的值,你可以像这样分配它:record: [this.caseProvider.record, Validators.compose([Validators.maxLength(30), Validators.pattern('.*[0-9].*')])]看看这个例子:stackoverflow.com/a/43279908/6294072

标签: angular ionic2


【解决方案1】:

您不需要使用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;
})

【讨论】:

  • 好的。感谢您的回复!如果我无法对它进行数据绑定,那么订阅值更改听起来像是下一个最好的事情。不过,这似乎是相当多的额外代码,尤其是在页面上有大量输入的情况下。我仍然希望我可以对它进行数据绑定,因为它会更干净,代码更少。 :-)
  • 好吧,您可以构建表单,使您从表单中获得的对象与您的caseProvider 的实例匹配,对吧?不太了解您的设置以及“我希望我的提供程序在每次更改时都更新” 在这里的含义,因此很难进一步提供帮助。
  • 因此,总而言之,您的回答听起来像是在说:FormControl 输入不能绑定到其他变量,因为它们已经绑定到 FormGroup。您可以做的最接近的事情是订阅 valueChanges,然后从那里手动设置 Provider 中的值?
  • 这里可能不是很了解,但我会尽快详细说明我的答案,让我们看看这是否是您所需要的。 caseProvider 是具有模型(类或接口)的对象吗?
  • 好主意。我当然可以向我的提供者添加一个接口,以便可以一次设置整个对象。谢谢!
【解决方案2】:

我找到了更多关于 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');
      }
  }
}

【讨论】:

    猜你喜欢
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 2018-09-22
    • 1970-01-01
    • 2018-05-09
    相关资源
    最近更新 更多