【问题标题】:Ionic 3 FormBuilder, How to validate ion-select ion-option?Ionic 3 FormBuilder,如何验证离子选择离子选项?
【发布时间】:2018-07-26 05:23:52
【问题描述】:

在ionic 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";
    }
  }

【问题讨论】:

    标签: angular mobile ionic2 ionic3 angular2-formbuilder


    【解决方案1】:

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

    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

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

    【讨论】:

    • 谢谢@Alex,我想要任何简短的解决方案(想想你是否想要为 14 个表格和 80 个变体下拉菜单做)。
    【解决方案2】:

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

    你所做的只是期望值是什么,它不能是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' : [''],
        });
      }
    

    希望这会有所帮助。

    【讨论】:

    • 我知道这可以通过自定义验证器来完成。在当前场景中,我有 14 个表格和 80 多个变体下拉列表。而且您的自定义验证器不可重用。我希望它是可重复使用的,并且不想更改表单。(有没有办法动态获取所有选项
    • @Ejaz47ok,我正在寻找一种更好更短的方法来做到这一点。但是你真的需要这样验证吗?我的意思是,用户不应该能够通过 javascript 设置表单值,或者这些值将来自其他表单,而您想确保它们相同?
    猜你喜欢
    • 2017-09-26
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2018-10-23
    • 2020-05-29
    • 2020-01-11
    相关资源
    最近更新 更多