You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:57:02