Angular 8级联<select>下拉失效求助:无法关联价格列表与货币
It looks like your cascading currency dropdown isn't working as expected due to two key issues: type mismatch with the selected index and reliance on fragile array indices. Let's walk through the fixes step by step.
Key Problems in Your Current Code
- String vs Number Index: When you use
(change)="selectedPriceListIndex = $event.target.value", the value from the event is a string, but yourselectedPriceListIndexis declared as a number. This mismatch can cause incorrect array lookups. - Unreliable Index Usage: Using the array index to access currencies assumes the
ListPricelistorder never changes. If the list is filtered, sorted, or updated later, your currency dropdown will break.
Recommended Solution: Use Reactive Form Value Changes
Since you're using Angular Reactive Forms, the cleanest approach is to subscribe to changes in the pricelist form control and fetch the corresponding pricelist object directly, instead of relying on indices.
Step 1: Update Your Component TS
Add a variable to hold the selected pricelist object, and set up a subscription to track form control changes:
import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; @Component({ // Your component metadata here }) export class YourComponent implements OnInit { f: FormGroup; submitted = false; filter: { ListPricelist: any[] }; // Replace 'any' with your actual pricelist type selectedPricelist: any; // Holds the full selected pricelist object constructor(private fb: FormBuilder) { // Initialize your form this.f = this.fb.group({ pricelist: [''], currency: [''] }); } ngOnInit(): void { // Subscribe to changes in the pricelist form control this.f.get('pricelist').valueChanges.subscribe(pricelistId => { // Find the matching pricelist object using its ID this.selectedPricelist = this.filter.ListPricelist.find(p => p.id === pricelistId); }); } // Your existing methods (like onSubmit) go here }
Step 2: Update Your HTML
Remove the (change) event from the pricelist dropdown, and update the currency dropdown to use the selected pricelist object:
<!-- Pricelist Dropdown --> <div class="flex2 pl10"> <select formControlName="pricelist" class="form-control" [ngClass]="{'is-invalid': submitted && f.pricelist.errors}" > <option value=""> Select a pricelist </option> <option *ngFor="let p of filter.ListPricelist" [ngValue]="p.id">{{p.label}}</option> </select> </div> <!-- Currency Dropdown --> <div class="flex2 pl10"> <select formControlName="currency" [ngClass]="{'is-invalid': submitted && f.currency.errors}" class="form-control"> <option value="">Select a currency</option> <option *ngFor="let c of selectedPricelist?.currencies" [ngValue]="c.id">{{c.code}}</option> </select> </div>
Alternative Fix: Fix the Index Type (Less Robust)
If you prefer to keep using the index approach (not recommended for long-term maintainability), convert the event value to a number using the + operator:
<!-- Pricelist Dropdown with Fixed Index Assignment --> <select formControlName="pricelist" class="form-control" (change)="selectedPriceListIndex = +$event.target.value" [ngClass]="{'is-invalid': submitted && f.pricelist.errors}" > <option value=""> Select a pricelist </option> <option *ngFor="let p of filter.ListPricelist; let i = index;" [ngValue]="p.id">{{p.label}}</option> </select>
This converts the string value from the event to a number, so selectedPriceListIndex will correctly reference the array index.
Additional Notes
- Remove Duplicate IDs: Your original code has
id="pricelist_id"inside the*ngFor, which creates multiple elements with the same ID (invalid HTML). Remove this or make it unique (e.g.,id="pricelist-{{i}}"). - Safe Navigation Operator: The
?.inselectedPricelist?.currenciesprevents Angular from throwing errors when no pricelist is selected yet.
内容的提问来源于stack exchange,提问作者Zephyr

