嘗試至少添加驗證以從 中選擇至少一項mat-select multipe option。當前在頁面加載時顯示錯誤訊息,直到用戶從選擇選項中選擇一項,這作業正常。
期望:
當我選擇全部或單個選擇時,錯誤訊息應該消失。(預期和作業正常)。
但是發生了什么:
當我取消選擇選定的單個專案時,未顯示必需的錯誤訊息。
不知道我做錯了什么。
SkillForm.component.ts
skillList = [
{ skillId: '0', skillName: 'JS' },
{ skillId: '1', skillName: 'TS' },
{ skillId: '2', skillName: 'JAVA' },
{ skillId: '3', skillName: '.Net' },
];
@ViewChild('pickAllCourse') private pickAllCourse: MatOption;
trainerForm = FormGroup;
constructor(public formBuilder: FormBuilder) { }
this.trainerForm = this.formBuilder.group({
selectedSkills :['', Validators.required, Validators.minLength(1)]
})
pickAll(): void {
if(this.pickAllCourse.selected) {
this.trainerForm.controls.selectedSkills.patchValue([...this.skillList.map((item) => item.deviceId), 0]);
} else {
this.trainerForm.controls.selectedSkills.patchValue([]);
}
}
selectOneItem(all): any {
if (this.pickAllCourse.selected) {
this.pickAllCourse.deselect();
return false;
}
if (this.trainerForm.controls.selectedSkills.value.length === this.skillList.length) {
this.pickAllCourse.select();
}
}
onSubmit(): void{
console.log('form value', this.trainerForm.value)
//
}
技能表單.component.html
<mat-form-field class="selectedSkills">
<mat-select multiple ngDefaultControl formControlName="selectedSkills"
placeholder="Select Device Type">
<mat-option #pickAllCourse (click)="pickAll()" [value]="0">All</mat-option>
<mat-option *ngFor="let i of skillList" [value]="i.deviceId"
(click)="selectOneItem(pickAllCourse.viewValue)">{{ i.skillName }}
</mat-option>
</mat-select>
<span class="text-danger" *ngIf="trainerForm.controls['selectedSkills '].invalid ">This field is required</span>
</mat-form-field>
此外,我需要有關如何在向后端提交表單時構造如下物件的幫助。
skillList: [
{skillId: '0'},
{skillId: '1'}
];
當我執行 console.log 時this.trainerForm.value,我看到skillList: ['0']
uj5u.com熱心網友回復:
問題和關注點
問題 1:
上的額外間距有拼寫錯誤trainerForm.controls['selectedSkills ']。
<span class="text-danger" *ngIf="trainerForm.controls['selectedSkills '].invalid ">This field is required</span>
問題 2:
如果表單控制元件需要多個Validators,則應將它們與 Array 分組。
this.trainerForm = this.formBuilder.group({
selectedSkills :['', Validators.required, Validators.minLength(1)]
})
改成:
this.trainerForm = this.formBuilder.group({
selectedSkills :['', [Validators.required, Validators.minLength(1)]]
})
關注 1
從 HTML 和 Typescript 部分,selectedSkills將回傳 的陣列number,但不會回傳Object. 當您使用item.deviceId(return string) 并且for 中deviceId不存在時。我假設您正在使用.ObjectskillListsitem.skillId
pickAll(): void {
if(this.pickAllCourse.selected) {
this.trainerForm.controls.selectedSkills.patchValue([...this.skillList.map((item) => item.deviceId), 0]);
} else {
this.trainerForm.controls.selectedSkills.patchValue([]);
}
}
<mat-option *ngFor="let i of skillList" [value]="i.deviceId"
(click)="selectOneItem(pickAllCourse.viewValue)">{{ i.skillName }}
</mat-option>
因此,當您 時console.log(this.trainerForm.value),它將顯示:
{ selectedSkills: [1, 2, 3] }
解決方案
- 對于
<mat-option>生成的*ngFor,設定[value]="{ skillId: i.skillId }"為將選定的值回傳為object。 - 添加
compareWith為您的<mat-select>. 宗旨,為比較this.trainerForm.controls.selectedSkills與[value]="{ skillId: i.skillId }"查詢/取消的選項中進行選擇時/取消選擇所有。
<mat-form-field class="selectedSkills">
<mat-select
multiple
ngDefaultControl
formControlName="selectedSkills"
placeholder="Select Device Type"
[compareWith]="compareFn"
>
<mat-option #pickAllCourse (click)="pickAll()" [value]="0"
>All</mat-option
>
<mat-option
*ngFor="let i of skillList"
[value]="{ skillId: i.skillId }"
(click)="selectOneItem(pickAllCourse.viewValue)"
>{{ i.skillName }}
</mat-option>
</mat-select>
<span
class="text-danger"
*ngIf="trainerForm.controls['selectedSkills'].invalid"
>This field is required</span
>
</mat-form-field>
- Set multiple
Validatorsin array[]as mentioned in Issue 2. pickAll()topatchValueforthis.trainerForm.controls.selectedSkillsas{ skillId: item.skillId }Object.onSubmit()before pass the form value to API, make sure you filterskillSetsvalue with{ skillId: item.skillId }Objectonly.compareFnis for comparing the selectedskillSetsvalue with each<mat-option>value. Hence, when Select All, all the<mat-option>will be selected and vice versa as (2).
trainerForm: FormGroup;
ngOnInit() {
this.trainerForm = this.formBuilder.group({
selectedSkills: ['', [Validators.required, Validators.minLength(1)]],
});
}
pickAll(): void {
if (this.pickAllCourse.selected) {
this.trainerForm.controls.selectedSkills.patchValue([
...this.skillList.map((item) => {
return {
skillId: item.skillId
};
}),
0,
]);
} else {
this.trainerForm.controls.selectedSkills.patchValue([]);
}
}
onSubmit(): void {
console.log('form value', this.trainerForm.value);
let postFormValue: any = {
...this.trainerForm.value,
selectedSkills: this.trainerForm.value.selectedSkills.filter(
(x: any) => typeof x === 'object'
),
};
console.log(postFormValue);
}
compareFn(obj1: any, obj2: any): boolean {
return obj1 && obj2 ? obj1.skillId === obj2.skillId : obj1 === obj2;
}
Sample Solution on StackBlitz
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/334777.html
標籤:javascript 有角的 打字稿 角反应形式 角形
