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

如何自定义mat tree的SelectionModel实现选中节点时禁用互斥节点复选框

Angular Material Tree 节点互斥选择实现方案

前置说明

我们默认你需要互斥的节点A、B可以通过唯一id识别,你可以根据实际业务调整判断条件(比如用name字段识别也可以)。

实现步骤

  • 步骤1:定义互斥节点标识集合
    在组件类中新增互斥节点配置,替换下面的A的id、B的id为你实际业务中两个互斥节点的id值:
// 新增:互斥节点ID集合
private mutuallyExclusiveIds: Set<string | number> = new Set(['A的id', 'B的id']);
  • 步骤2:新增节点禁用状态判断方法
    新增方法用于判断指定节点是否需要禁用:
// 新增:判断节点是否禁用
isNodeDisabled(node: ExampleFlatNode): boolean {
  // 不在互斥组内的节点不禁用
  if (!this.mutuallyExclusiveIds.has(node.id)) {
    return false;
  }
  // 已选列表中存在互斥组内的其他节点时,当前节点禁用
  return this.checklistSelection.selected.some(selectedNode => 
    this.mutuallyExclusiveIds.has(selectedNode.id) && selectedNode.id !== node.id
  );
}
  • 步骤3:修改节点选择逻辑,选中互斥节点时自动清除同组其他节点的选中状态
    分别修改父节点切换方法todoItemSelectionToggle和叶子节点切换方法todoLeafItemSelectionToggle,新增互斥逻辑:
todoItemSelectionToggle(node: ExampleFlatNode): void {
  this.checklistSelection.toggle(node);
  const descendants = this.treeControl.getDescendants(node);
  this.checklistSelection.isSelected(node)
    ? this.checklistSelection.select(...descendants)
    : this.checklistSelection.deselect(...descendants);

  // ========== 新增:互斥逻辑开始 ==========
  if (this.mutuallyExclusiveIds.has(node.id) && this.checklistSelection.isSelected(node)) {
    // 找到同组其他已选的互斥节点,取消选中
    this.checklistSelection.selected.forEach(selectedNode => {
      if (this.mutuallyExclusiveIds.has(selectedNode.id) && selectedNode.id !== node.id) {
        this.checklistSelection.deselect(selectedNode);
        // 同时取消该节点所有子节点的选中
        const otherDescendants = this.treeControl.getDescendants(selectedNode);
        this.checklistSelection.deselect(...otherDescendants);
      }
    });
  }
  // ========== 新增:互斥逻辑结束 ==========

  descendants.every(child =>
    this.checklistSelection.isSelected(child)
  );
}

todoLeafItemSelectionToggle(node: ExampleFlatNode): void {
  this.checklistSelection.toggle(node);

  // ========== 新增:互斥逻辑开始 ==========
  if (this.mutuallyExclusiveIds.has(node.id) && this.checklistSelection.isSelected(node)) {
    // 找到同组其他已选的互斥节点,取消选中
    this.checklistSelection.selected.forEach(selectedNode => {
      if (this.mutuallyExclusiveIds.has(selectedNode.id) && selectedNode.id !== node.id) {
        this.checklistSelection.deselect(selectedNode);
        // 如果是父节点还要取消子节点选中
        const otherDescendants = this.treeControl.getDescendants(selectedNode);
        this.checklistSelection.deselect(...otherDescendants);
      }
    });
  }
  // ========== 新增:互斥逻辑结束 ==========

  const a=of(this.checklistSelection.selected);
}
  • 步骤4:修改模板绑定禁用状态
    找到你的组件模板中渲染树节点复选框的代码,给mat-checkbox绑定disabled属性:
<mat-checkbox
  [checked]="checklistSelection.isSelected(node)"
  [disabled]="isNodeDisabled(node)" <!-- 新增这一行 -->
  (click)="$event.stopPropagation()"
  (change)="你原来的选择触发方法,比如todoItemSelectionToggle(node)或者todoLeafItemSelectionToggle(node)"
>
  {{node.name}}
</mat-checkbox>

扩展说明

如果需要多组互斥节点,你可以将mutuallyExclusiveIds修改为数组格式,存储多组互斥ID集合,调整判断逻辑即可适配。

内容的提问来源于stack exchange,提问作者MILAD BAHARLO

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:27:05