Angular自定义表格:下拉框控制对应行单元格可编辑问题
Hey there! The problem you're facing is that you're using a single expression boolean variable to control editability for all rows. When you update this variable, every row reacts to the same value—hence why all "New Age" fields become editable at once. Let's adjust this to track edit states per individual row instead.
Step 1: Update Component Logic (app.component.ts)
Instead of a single boolean, use an object to store the edit state for each row. We can use the person's name (or a unique ID) as the key to track which row should be editable:
export class AppComponent { title = 'my-app'; // Object to track edit state per row (key: person's name, value: boolean) editStates: { [name: string]: boolean } = {}; editAge(personName: string, selectedValue: string) { // Set edit state to true only if selected value is '2' this.editStates[personName] = selectedValue === '2'; } }
Step 2: Update Template (app.component.html)
Modify each row to reference the specific edit state for that person, and pass the person's name to the editAge method:
<table border="1"> <tr> <td>Name</td> <td>Age</td> <td>New Age</td> </tr> <tr> <td>John</td> <td> <select (change)="editAge('John', selectField1.value)" #selectField1> <option value="1">Less than 10</option> <option value="2">Greater than 10 and Less than 80</option> <option value="3">Less than 80</option> </select> </td> <td> <span *ngIf="!editStates['John']">24</span> <span *ngIf="editStates['John']"><input type="text" /></span> </td> </tr> <tr> <td>Jacky</td> <td> <select (change)="editAge('Jacky', selectField2.value)" #selectField2> <option value="1">Less than 10</option> <option value="2">Greater than 10 and Less than 80</option> <option value="3">Less than 80</option> </select> </td> <td> <span *ngIf="!editStates['Jacky']">4</span> <span *ngIf="editStates['Jacky']"><input type="text" /></span> </td> </tr> <tr> <td>Roy</td> <td> <select (change)="editAge('Roy', selectField3.value)" #selectField3> <option value="1">Less than 10</option> <option value="2">Greater than 10 and Less than 80</option> <option value="3">Less than 80</option> </select> </td> <td> <span *ngIf="!editStates['Roy']">34</span> <span *ngIf="editStates['Roy']"><input type="text" /></span> </td> </tr> </table>
How This Works
- We now have a unique edit state for each row, stored in the
editStatesobject. - When the dropdown changes, we pass the person's name along with the selected value to
editAge, which updates only that row's state. - Each "New Age" cell checks its own row's edit state, so only the corresponding row becomes editable when the dropdown selects value '2'.
Bonus: Scalable Approach (For Dynamic Rows)
If you ever load rows dynamically (e.g., from an API), you can store your data in an array of objects with an isEditable property to keep code clean:
// Example dynamic data people = [ { name: 'John', currentAge: 24, isEditable: false }, { name: 'Jacky', currentAge: 4, isEditable: false }, { name: 'Roy', currentAge: 34, isEditable: false } ]; editAge(person: any, selectedValue: string) { person.isEditable = selectedValue === '2'; }
Then in the template, use *ngFor to loop through the array:
<tr *ngFor="let person of people"> <td>{{ person.name }}</td> <td> <select (change)="editAge(person, $event.target.value)"> <option value="1">Less than 10</option> <option value="2">Greater than 10 and Less than 80</option> <option value="3">Less than 80</option> </select> </td> <td> <span *ngIf="!person.isEditable">{{ person.currentAge }}</span> <span *ngIf="person.isEditable"><input type="text" [(ngModel)]="person.currentAge" /></span> </td> </tr>
内容的提问来源于stack exchange,提问作者Rijo

