Angular如何遍历表单中的多个选择器并校验是否全部完成选择
解决思路
- 新增存储每个文件选择结果的变量
你需要先在组件中定义数组存储每个文件对应的来源和运动项目选择值,解决原来没有绑定选择结果的问题。 - 给下拉框绑定双向数据绑定
用Angular的[(ngModel)]将每个下拉框和对应文件的选择值绑定,同时给<option>设置value属性获取选中值。 - 实现表单校验逻辑
编写校验方法判断所有下拉框是否都选择了非默认的有效值,规则如下:
- 若开启单来源(
singleSource=true),则来源项默认全局有效,无需校验 - 若未开启单来源,则校验所有文件的来源选择都不是默认的
Select Source - 运动项目的校验逻辑和来源完全一致
- 控制提交按钮可用性
根据校验结果动态禁用/启用Proceed按钮,未完成所有选择时用户无法点击提交。
完整修改代码
组件代码
import { Component, Input, OnInit } from '@angular/core'; @Component({ selector: 'app-selector-table', templateUrl: './selector-table.component.html', styleUrls: ['./selector-table.component.css'], }) export class SelectorTableComponent implements OnInit { // Properties proceed = false; // 存储每个文件的选择结果 fileSelections: Array<{fileName: string, source: string, sport: string}> = []; readonly DEFAULT_SOURCE = 'Select Source'; readonly DEFAULT_SPORT = 'Select Sport'; //Inputs @Input() singleSource!: boolean; @Input() selectedSource!: string; @Input() singleSport!: boolean; @Input() selectedSport!: string; @Input() fileNames!: string[]; @Input() availableSources!: string[]; @Input() availableSports!: string[]; // Constructor constructor() {} readyToProceed() { this.proceed = true; // 后续可以在这里拿到所有fileSelections的值做提交逻辑 } // 表单校验方法 isFormValid(): boolean { // 校验来源 const sourceValid = this.singleSource || this.fileSelections.every(item => item.source !== this.DEFAULT_SOURCE); // 校验运动项目 const sportValid = this.singleSport || this.fileSelections.every(item => item.sport !== this.DEFAULT_SPORT); return sourceValid && sportValid; } ngOnInit(){ this.availableSources.unshift(this.DEFAULT_SOURCE) this.availableSports.unshift(this.DEFAULT_SPORT) // 初始化每个文件的默认选择值 this.fileSelections = this.fileNames.map(fileName => ({ fileName, source: this.DEFAULT_SOURCE, sport: this.DEFAULT_SPORT })) } }
模板代码
<div style=" margin: 8px; padding: 8px 5px; color: #333; width: auto; cursor: pointer; text-align: center; " > <h2>Selector table</h2> <table style="margin-left: auto; margin-right: auto; min-width: 50%"> <tr style="padding-left: 8px; text-align: left; font-weight: bolder"> <td style="min-width: 40%">File name</td> <td>Source</td> <td>Sport</td> </tr> <tr *ngFor="let selection of fileSelections; let i = index"> <td style="text-align: left">{{ selection.fileName }}</td> <td style="text-align: left"> <div *ngIf="singleSource"> {{ selectedSource }} </div> <div *ngIf="!singleSource"> <select style="min-width: 10rem;" [(ngModel)]="selection.source"> <option *ngFor='let source of availableSources' [value]="source">{{source}}</option> </select> </div> </td> <td style="text-align: left"> <div *ngIf="singleSport"> {{ selectedSport }} </div> <div *ngIf="!singleSport"> <select style="min-width: 10rem;" [(ngModel)]="selection.sport"> <option *ngFor='let sport of availableSports' [value]="sport">{{sport}}</option> </select> </div> </td> </tr> </table> <button style="margin-top: 20px;" (click)="readyToProceed()" [disabled]="!isFormValid()">Proceed</button> </div>
注意事项
你需要在当前组件所属的Angular模块中导入FormsModule,否则[(ngModel)]双向绑定会失效,导入示例如下:
// 对应模块文件中 import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ // 其他导入 FormsModule ], // 其他配置 }) export class YourModule { }
内容的提问来源于stack exchange,提问作者Ruben Ferreira
相关产品推荐
相关产品推荐

