Angular 5中根据其他字段值设置表单字段必填性的问题
Got it, let's fix this so your X-Axis and Y-Axis are only required when selecting bar or line graphs. The key here is to dynamically add or remove validators based on the selected graph type, and adjust the error messages to only show when relevant.
Step 1: Update the Component TypeScript Code
First, we'll modify the form setup to remove initial required validators for X and Y axes, then add a listener to the graph type selection to toggle those validators. We'll also clean up any unused code and add proper subscription management to avoid memory leaks.
import { Component, OnInit, OnDestroy } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { Subscription } from 'rxjs'; // Import Subscription @Component({ selector: 'app-client', templateUrl: './client.component.html', styleUrls: ['./client.component.css'] }) export class ClientComponent implements OnInit, OnDestroy { // Add OnDestroy interface clientForm: FormGroup; // Dropdown arrays public dimensions: string[] = ['Plant','Year','Month']; public types: string[] = ['bar','line','pie','doughnut']; private typeSubscription: Subscription; // Store subscription to clean up later constructor(private form: FormBuilder) { } // Remove unused FormsModule injection ngOnInit() { this.clientForm = this.form.group({ 'type': [null, Validators.required], 'xAxis': [null], // No initial required validator 'yAxis': [null] // No initial required validator }); // Listen for changes in the selected graph type this.typeSubscription = this.clientForm.get('type').valueChanges.subscribe(selectedType => { const xAxisControl = this.clientForm.get('xAxis'); const yAxisControl = this.clientForm.get('yAxis'); if (selectedType === 'bar' || selectedType === 'line') { // Add required validator for bar/line graphs xAxisControl.setValidators(Validators.required); yAxisControl.setValidators(Validators.required); } else { // Clear validators for pie/doughnut graphs xAxisControl.clearValidators(); yAxisControl.clearValidators(); } // Update control validity without emitting an event to avoid infinite loops xAxisControl.updateValueAndValidity({ emitEvent: false }); yAxisControl.updateValueAndValidity({ emitEvent: false }); }); } ngOnDestroy() { // Clean up subscription to prevent memory leaks if (this.typeSubscription) { this.typeSubscription.unsubscribe(); } } changeGraph() { // Your existing submit logic here } }
Key Changes in TS:
- Removed unused
FormControldeclarations andFormsModuleinjection (you don't need to injectFormsModuleinto the constructor). - Initialized X and Y axis controls without required validators since they should only be required conditionally.
- Added a
valueChangessubscription to thetypecontrol to dynamically adjust validators based on user selection. - Implemented
ngOnDestroyto unsubscribe from the subscription, preventing memory leaks. - Used
updateValueAndValidity({ emitEvent: false })to refresh control status without triggering another change event (avoids infinite loops).
Step 2: Update the HTML Template
Next, we need to adjust the error messages for X-Axis and Y-Axis to only display when the selected graph type is bar or line. This ensures users don't see unnecessary error messages for pie/doughnut graphs.
<form [formGroup]="clientForm" (ngSubmit)="clientForm.valid && changeGraph()" #formLogin="ngForm"> <div class="form-group"> <label> Graph Type </label> <select class="form-control" formControlName="type"> <option disabled [ngValue]="null"> Select Option </option> <option *ngFor='let t of types' [ngValue]="t"> {{t}} </option> </select> <div class="form-err" *ngIf="(clientForm.controls['type'].hasError('required') && clientForm.controls['type'].touched) || (clientForm.controls['type'].hasError('required') && formLogin.submitted)"> Please enter Graph Type </div> </div> <div class="form-group"> <label> X-Axis </label> <select class="form-control" formControlName="xAxis"> <option disabled [ngValue]="null"> Select Option </option> <option *ngFor='let dim of dimensions' [ngValue]="dim"> {{dim}} </option> </select> <!-- Only show error if type is bar/line and validation fails --> <div class="form-err" *ngIf="(clientForm.controls['type'].value === 'bar' || clientForm.controls['type'].value === 'line') && ((clientForm.controls['xAxis'].hasError('required') && clientForm.controls['xAxis'].touched) || (clientForm.controls['xAxis'].hasError('required') && formLogin.submitted))"> Please enter Dimension </div> </div> <div class="form-group"> <label> Y-Axis </label> <select class="form-control" formControlName="yAxis"> <option disabled [ngValue]="null"> Select Option </option> <option *ngFor='let dim of dimensions' [ngValue]="dim"> {{dim}} </option> </select> <!-- Only show error if type is bar/line and validation fails --> <div class="form-err" *ngIf="(clientForm.controls['type'].value === 'bar' || clientForm.controls['type'].value === 'line') && ((clientForm.controls['yAxis'].hasError('required') && clientForm.controls['yAxis'].touched) || (clientForm.controls['yAxis'].hasError('required') && formLogin.submitted))"> Please enter Measure </div> </div> <button class="client-side-window-btn" type="submit"> Save </button> </form>
Key Changes in HTML:
- Updated the error message conditions for X-Axis and Y-Axis to include a check for the selected graph type (
barorline). - Fixed the
dimensionsreference (original haddimensions?.databut your TS definesdimensionsas a string array, so changed todimensions).
Now, when you select bar or line, the X and Y axes will become required fields with appropriate error messages. For pie or doughnut, those fields will be optional, and their error messages won't appear at all.
内容的提问来源于stack exchange,提问作者Mrinalini Pal

