首页 > 解决方案 > 材质树父节点未按预期工作

问题描述

我做了一个可选择的材质树,最多可选择 42 个元素。当我达到限制 (42) 时,节点将被禁用。问题是当我达到限制并且我从一个家庭中选择了一些孩子并禁用了一些孩子时,父节点被部分选择,所以当我手动取消选择一个孩子并再次选择父节点时它会很奇怪。

在此处输入图像描述

上图不正确。父节点应标记为“全部选中”

在此处输入图像描述

上图是对的

在此处输入图像描述

当我取消选择孩子、选择父母和取消选择父母时,就会发生这种情况。这是代码。

  descendantsAllSelected(productNodeFlat: ProductNodeFlat): boolean {
    if (this.treeControl.dataNodes) {
      const descendants = this.treeControl.getDescendants(productNodeFlat);
      return descendants.every(child => this.productNodeFlatSelection.isSelected(child));
    }
    return false;
  }

  descendantsPartiallySelected(productNodeFlat: ProductNodeFlat): boolean {
    if (this.treeControl.dataNodes) {
      const descendants = this.treeControl.getDescendants(productNodeFlat);
      const result = descendants.some(child => this.productNodeFlatSelection.isSelected(child));
      return result && !this.descendantsAllSelected(productNodeFlat);
    }
    return false;
  }

标签: angularangular-materialangular8

解决方案


您的 'all selected' 功能需要考虑节点是否被禁用,因为 all selected 意味着所有子节点都处于 selected或 disabled状态。我不知道你如何存储禁用状态,所以我在child.disabled这里用它来表示。就像是:

descendantsAllSelected(productNodeFlat: ProductNodeFlat): boolean {
  if (this.treeControl.dataNodes) {
    const descendants = this.treeControl.getDescendants(productNodeFlat);
    return descendants.every(child => 
      this.productNodeFlatSelection.isSelected(child) || child.disabled
    );
  }

  return false;
}

另一种方法是检查选择的数量是否等于最大允许值。

您的“部分选中”功能还需要考虑节点是否“禁用”,您还可以通过简单检查第一个选中和第一个未选中和未禁用来提高效率。这只需要通过节点进行一次迭代:

descendantsPartiallySelected(productNodeFlat: ProductNodeFlat): boolean {
  if (this.treeControl.dataNodes) {
    let selected = false;
    let unselected = false;
    const descendants = this.treeControl.getDescendants(productNodeFlat);
    return descendants.some(child => {
      if (this.productNodeFlatSelection.isSelected(child)) {
        selected = true;
      }
      else if (!child.disabled) {
        notselected = true;
      }
      return selected && notselected;
    });
  }

  return false;
}

推荐阅读