Angular 2使用ngFor实现动态下拉框的技术咨询
Let's walk through getting your dynamic dropdowns working correctly—your current code has a few key issues with loop scope, data binding, and variable references that we'll straighten out step by step.
1. First, Clean Up Your Component Data & Structure
Your provided response array holds question objects, but your template references responseoption without clear context. Let's define a proper data structure in your component to link each question to its dropdown options (we'll also add a property to track each dropdown's selected value):
// In your component.ts file import { Component } from '@angular/core'; // Define interfaces to type your data (optional but highly recommended) interface DropdownOption { id: number; name_eng: string; } interface Question { val_id: number; role_id: number; id: number; is_optional: boolean; is_text: boolean; selectedValue?: number; // Tracks the selected option ID for this question options: DropdownOption[]; // The options specific to this question } @Component({ selector: 'app-dynamic-dropdowns', templateUrl: './dynamic-dropdowns.component.html' }) export class DynamicDropdownsComponent { // Your original question data, now paired with dropdown options questions: Question[] = [ { val_id:1, role_id:1, id:1, is_optional:false, is_text:false, options: [ { id: 101, name_eng: 'Admin Role' }, { id: 102, name_eng: 'Editor Role' } ]}, { val_id:1, role_id:1, id:2, is_optional:false, is_text:false, options: [ { id: 201, name_eng: 'Read Access' }, { id: 202, name_eng: 'Write Access' } ]}, { val_id:1, role_id:1, id:3, is_optional:false, is_text:false, options: [ { id: 301, name_eng: 'Active' }, { id: 302, name_eng: 'Inactive' } ]} ]; // Updated handler to receive both the selected value and the related question GetDataselected(selectedValue: string, question: Question) { const selectedId = parseInt(selectedValue, 10); console.log(`Question ${question.id} selected option ID:`, selectedId); // Add your business logic here (e.g., update form data, call an API) } }
2. Fix the HTML Template
Your original template had mismatched loop variables and incorrect ngModel binding. Here's the corrected version:
<!-- In your component's HTML template --> <div *ngFor="let question of questions" class="row mb-3"> <!-- Bind the select ID to the question's unique ID (avoids duplicate IDs) --> <select id="dropdown-{{question.id}}" class="dropdown" <!-- Bind ngModel to the current question's selectedValue property --> [(ngModel)]="question.selectedValue" <!-- Pass both the selected value and question to your handler --> (change)="GetDataselected($event.target.value, question)" > <!-- Optional: Add a default empty option to improve UX --> <option value="">Select an option</option> <!-- Loop through the current question's options --> <option *ngFor="let option of question.options" [value]="option.id" <!-- Bind the option's value to its unique ID --> > {{option.name_eng}} </option> </select> </div>
Key Fixes & Explanations
- Proper Loop Scope: The inner
*ngFornow iterates overquestion.optionsinstead of an undefinedresponseoption, ensuring each dropdown gets the correct options for its question. - Independent Selection Tracking: We bind
[(ngModel)]toquestion.selectedValueinstead of a global variable, so each dropdown maintains its own selected state without interfering with others. - Valid ID Attribute: The select ID uses
question.id(with a prefix) instead ofoption?.id—the original reference was invalid becauseoptiondoesn't exist in the outer loop's scope. - Useful Event Handler: The
(change)event now passes both the selected value and the related question, making it easy to handle selections per question in your component logic. - Better UX: The empty default option ensures users explicitly make a selection instead of having a random option pre-selected.
If your responseoption is a shared list of options for all dropdowns (not per question), just define a global responseOptions array in your component and change the inner loop to *ngFor="let option of responseOptions"—the rest of the binding logic stays nearly identical.
内容的提问来源于stack exchange,提问作者PAR

