在ionic 3中,FormBuilder检查表单的有效性,我们使用formGroup的"form.valid">属性,如果有效则返回true,如果无效则返回false,
我的问题是当我从 javascript 设置值时,"form.valid">甚至设置在选择控件的选项中未给出(可用)的任何值也会给出true。
如果选择值与给定选项不同,我希望选择控件无效。
这是有效的 Plunker 链接,
代码说话更好,
这是设计部分(页面.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";
}
}
你需要的是一个自定义验证器。
你这样做的方式只是期望值是某种东西,它不能null
或undefined
,所以任何值都会通过所需的验证器。
要创建自定义验证器,您需要一个.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' : [''],
});
}
希望这有帮助。
我会将选项更改为数组,在模板中迭代它们。当您想尝试为表单设置值时,请检查它们是否存在于相应的数组中,如果是,请设置值,否则留空。这样,我们可以检查表单是否有效。无论如何,我认为最好在模板中迭代数组以保持其干净并处理组件中的其他任何内容。所以做这样的事情:
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
您可能希望将这些数组转换为对象数组,选项的显示名称和选项的值。