Ionic 3 FormBuilder,如何验证离子选择离子选项?

时间:2018-02-15 12:37:42

标签: angular mobile ionic2 ionic3 angular2-formbuilder

在离子3中,FormBuilder用于检查表单的有效性,我们使用formGroup的" form.valid" 属性,如果有效则返回true,如果无效则返回false,

我的问题是当我从javascript设置值时," form.valid" 提供 true 甚至设置任何未给出的值(可用) )在选择控件的选项中。

如果选择值与给定选项不同,我希望选择控件无效。

这是工作Plunker link

代码说得更好,

以下是设计部分(page.html)

<button ion-button color="app" (click)="setval_valid()">Set valid values</button>
  <button ion-button color="app" (click)="setval()">Set Different invalid values</button>
  <form [formGroup]="knowledge" *ngIf="!retryButton">
        <ion-list>
                <ion-item>
                    <ion-label floating>Educational Qualification Details <span>*</span></ion-label>
                    <ion-select formControlName="f2_edudetail" interface="popover" (change)="getTotal()">
                        <ion-option value="illiterate"> Illiterate </ion-option> 
                        <ion-option value="primary education"> Education </ion-option> 
                        <ion-option value="matriculate"> Matriculate </ion-option> 
                        <ion-option value="graduate"> Graduate </ion-option> 
                        <ion-option value="post graduate"> Post Graduate </ion-option> 
                    </ion-select>
                </ion-item>
                <div *ngIf="!knowledge.controls.f2_edudetail.valid  && (knowledge.controls.f2_edudetail.dirty || submitAttempt)">
            <p *ngIf="knowledge.controls.f2_edudetail.errors.required">This field is required.</p>
        </div>


                <ion-item>
                    <ion-label floating>What Is Your Proficiency In English?<span>*</span></ion-label>
                    <ion-select formControlName="f2_proficiency" interface="popover">
                      <ion-option value="fluent">Fluent</ion-option>
                      <ion-option value="read only">Read Only</ion-option>
                      <ion-option value="write only">Write Only</ion-option>
                      <ion-option value="speak only">Speak Only</ion-option>
                      <ion-option value="understand only">Understand Only</ion-option>
                      <ion-option value="Don't Know">Don't Know</ion-option>
                    </ion-select>
                </ion-item>
                <div *ngIf="!knowledge.controls.f2_proficiency.valid  && (knowledge.controls.f2_proficiency.dirty || submitAttempt)">
            <p *ngIf="knowledge.controls.f2_proficiency.errors.required">This field is required.</p>

        </div>


                <ion-item>
                    <ion-label floating>Participation In Farming Programs</ion-label>
                    <ion-select formControlName="f2_participation" interface="popover" (ionChange)="setValidation()">
                      <ion-option value="yes">Yes</ion-option>
                      <ion-option value="no">No</ion-option>
                    </ion-select>
                </ion-item>
        </ion-list>     
    </form>

    <button ion-button color="app" (click)="save()">Save</button>

    <br><br>

    <b>{{validity}}</b>

这是TS部分(page.ts)

knowledge: FormGroup;
  validity:stirng = '';

  constructor(public navController: NavController, public formBuilder: FormBuilder) 
  {
    this.knowledge = formBuilder.group({
            'f2_edudetail' : ['', Validators.required], //drp
            'f2_proficiency' : ['', Validators.required], //drp
            'f2_participation' : [''], //drp
    });

  }

  setval(){

    let formData = [];
        formData['f2_edudetail']     = "Blah Blah";
        formData['f2_proficiency']   = "Blah Blah";
        formData['f2_participation'] = "Blah Blah";

    this.knowledge.setValue(formData);
    this.validity = '';
  }

  setval_valid(){

    let formData = [];
        formData['f2_edudetail']     = "illiterate";
        formData['f2_proficiency']   = "fluent";
        formData['f2_participation'] = "yes";

    this.knowledge.setValue(formData);
    this.validity = '';
  }

  save(){
    if (this.knowledge.valid){
      this.validity = "Valid (I want this to be invalid if select values are different from the given option)";
    }
    else{
      this.validity = "Invalid";
    }
  }

2 个答案:

答案 0 :(得分:1)

您需要的是自定义验证器。

您完成它的方式只是期望值是某种东西,它不能是nullundefined,因此任何值都会传递所需的验证器

要创建自定义验证程序,您需要.ts文件来创建验证程序类,我们可以将其称为example.ts

import { FormControl } from '@angular/forms';

export class MyCustomValidator {
    static isValid = (control: FormControl): any => {
        // The value coming from the control
        let myProp: string = String(control.value);

         // Will check if it's different from the desired options. 
        if (myProp != 'fluent' && myProp != 'read only' && myProp != 'write only' && myProp != 'speak only' && myProp != 'understand only' && myProp != "Don't Know"){
            // if different, return a property invalid with value true
            return {
                "invalid": true
            };
        };

        // If it doesn't enter the if statement then it's valid, so return null
        return null;
    }
}

然后在您的page.ts中,您将导入验证程序并在Validators.compose

中使用它
import { MyCustomValidator } from 'path/to/your/file/example';

knowledge: FormGroup;

  constructor(public navController: NavController, public formBuilder: FormBuilder) 
  {
    this.knowledge = formBuilder.group({
            'f2_edudetail' : ['', Validators.required],
            'f2_proficiency' : ['', Validators.compose([Validators.required, MyCustomValidator.isValid])], //here's your custom validator being used
            'f2_participation' : [''],
    });
  }

希望这有帮助。

答案 1 :(得分:0)

我会将选项更改为数组,在模板中迭代它们。如果要尝试为表单设置值,请检查它们是否存在于相应的数组中,如果存在,则设置值,否则保留为空。通过这种方式,我们可以检查表单是否有效。无论如何,我认为在模板中迭代数组以保持其清洁并处理组件中的任何其他内容会更好。所以做这样的事情:

TS:

firstOptions = ['illiterate','primary education']
secondOptions = ['fluent', 'read only']
thirdOptions = ['yes', 'no']

HTML:

<ion-select formControlName="f2_edudetail" interface="popover" (change)="getTotal()">
  <ion-option *ngFor="let opt of firstOptions" [value]="opt"> {{opt}}</ion-option> 
</ion-select>

// rest of selects

然后在设置值时,检查它们是否在数组中找到:

setval(){
  let formData = [];
    formData['f2_edudetail']     = this.firstOptions.find(x => x === "blah") || '';
    formData['f2_proficiency']   = this.secondOptions.find(x => x === "blah") || '';
    formData['f2_participation'] = this.thirdOptions.find(x => x === "blah") || '';

  this.knowledge.setValue(formData);
  this.validity = '';
}

您的演示:https://plnkr.co/edit/uuhMn0sS5VCyL4dZDjRG?p=preview

您可能希望将这些数组转换为对象数组,并使用选项的显示名称和选项的值。