Angular 5+Firebase CRUD:点击仅展开选中用户编辑表单问题
解决Angular中点击编辑按钮仅展开当前用户表单的问题
嗨,我完全懂你现在的困扰——你用了一个全局的editForm布尔变量来控制表单显示,所以不管点哪个用户的编辑按钮,所有用户行的表单都会一起展开或收起。这是因为所有<tr>都绑定了同一个状态变量,咱们得改成每个用户单独控制自己的编辑状态,下面给你两种实用的解决方法:
方法一:给每个用户对象添加编辑状态属性
这种方法直接给每个用户实例加一个临时的isEditing字段,用来控制当前用户的表单是否显示:
1. 修改组件代码,给用户添加编辑状态
在获取Firebase数据的时候,给每个用户对象加上isEditing属性(默认设为false,不会同步回数据库,只是前端临时状态):
export class UsersComponent implements OnInit { userList: User[]; // 删掉原来的editForm变量,不用全局控制了 constructor(private userService: UserService) {} ngOnInit() { var x = this.userService.getData(); x.snapshotChanges().subscribe(item => { this.userList = []; item.forEach(element => { var y = element.payload.toJSON(); y['$key'] = element.key; // 给每个用户添加编辑状态,默认关闭 y['isEditing'] = false; this.userList.push(y as User); }) }) } openEdit(user: User) { // 切换当前点击用户的编辑状态 // 可选:如果想同时只允许一个表单打开,先把所有用户的状态设为false // this.userList.forEach(u => u.isEditing = false); user.isEditing = !user.isEditing; // 别忘了把当前用户赋值给service的selectedUser,确保表单绑定正确 this.userService.selectedUser = {...user}; } }
2. 修改模板代码,绑定当前用户的编辑状态
把原来的*ngIf="editForm"改成绑定当前用户的isEditing属性:
<tbody> <tr *ngFor="let user of userList; let i = index"> <!-- 原来的td内容保持不变 --> <td>{{i + 1}}</td> <td> {{user.nickName}} </td> <!-- ...其他td... --> <td> <a (click)="openEdit(user)"> <button class="btn btn-primary"> <i class="fas fa-edit"></i> </button> </a> </td> <!-- ...删除按钮td... --> <!-- 这里改成绑定user.isEditing --> <td *ngIf="user.isEditing"> <form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)"> <!-- 表单内容保持不变 --> </form> </td> </tr> </tbody>
方法二:维护当前编辑用户的唯一标识
如果不想修改用户对象,也可以单独用一个变量存储当前正在编辑的用户$key(Firebase生成的唯一键):
1. 修改组件代码
export class UsersComponent implements OnInit { userList: User[]; // 存储当前正在编辑的用户key,默认为null表示没有编辑状态 currentEditingKey: string | null = null; constructor(private userService: UserService) {} ngOnInit() { // 这里的代码和原来一样,不用修改 var x = this.userService.getData(); x.snapshotChanges().subscribe(item => { this.userList = []; item.forEach(element => { var y = element.payload.toJSON(); y['$key'] = element.key; this.userList.push(y as User); }) }) } openEdit(user: User) { // 如果点击的是当前正在编辑的用户,就关闭编辑;否则切换到该用户 this.currentEditingKey = this.currentEditingKey === user.$key ? null : user.$key; // 同步更新selectedUser this.userService.selectedUser = {...user}; } }
2. 修改模板代码
把表单的*ngIf改成判断当前用户的$key是否等于currentEditingKey:
<td *ngIf="user.$key === currentEditingKey"> <form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)"> <!-- 表单内容保持不变 --> </form> </td>
额外注意点
- 不管用哪种方法,都要在
openEdit里把当前用户浅拷贝后赋值给userService.selectedUser(比如this.userService.selectedUser = {...user};),避免直接修改原数组里的用户对象,导致列表显示异常。 - 如果你的
User接口没有isEditing字段,要么更新接口定义,要么用any类型,或者在赋值时用类型断言。
内容的提问来源于stack exchange,提问作者user9753313
相关产品推荐
相关产品推荐

