Primeng树选择组件带有多个选择的组件不要从编辑表单中显示预选数据

发布于 2025-02-11 14:07:57 字数 4628 浏览 2 评论 0原文

我用Primeng树或Treelect组件的编辑形式有问题(我两者都尝试过)。问题是数据由API以ID,项目,产品和版本的实体形式提供。从理论上讲,一个项目可以包含许多产品,并且产品可以包含许多版本(这就是为什么我在树上显示的原因)。因此,我在节点模型中将数据从API转换。对于创建表格,没问题,但是对于编辑表单,无法有效地显示预选的数据。我能做的最好的是选择了最后一个儿童(版本),但父母和父母没有扩大。

component.ts:

  productSoftwareVersionsNodes: TreeNode[] = [];
  productSoftwareVersionsSelected: TreeNode[] = [];

  versionToTreeNode(version: IVersionForNode): TreeNode {
    return {
      label: version.version,
      data: version.id,
      key: version.id!.toString()
    }
  }

  productToTreeNode(product: IProductForNode, project: IProjectForNode): TreeNode {
    const versionsNodes: TreeNode[] = [];

    if(product.versions !== undefined){
      product.versions.forEach(version => versionsNodes.push(this.versionToTreeNode(version)));
    }

    return {
      label: product.product,
      key: project.project + "_" + product.product,
      selectable: false,
      data: product.product,
      children: versionsNodes
    }
  
  }

  projectToTreeNode(project: IProjectForNode): TreeNode {

    const productsNodes: TreeNode[] = [];

    if(project.products !== undefined){
      project.products.forEach(product => productsNodes.push(this.productToTreeNode(product, project)));
    }

    return {
      label: project.project,
      data: project.project,
      key: project.project,
      selectable: false,
      // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
      icon: 'flag-icon flag-icon-' + project.countryCode,
      children: productsNodes
    }
    
  }

  selectedVersionToTreeNode(project: IProjectForNode, product: IProductForNode,version: IVersionForNode): TreeNode {

    const projectNode: TreeNode = {
      label: project.project,
      data: project.project,
      key: project.project,
      selectable: false,
      expanded: true,
      partialSelected: true,
      // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
      icon: 'flag-icon flag-icon-' + project.countryCode
    };

    const productNode: TreeNode = {
      label: product.product,
      data: product.product,
      key: project.project + "_" + product.product,
      selectable: false,
      expanded: true,
      partialSelected: true,
      parent: projectNode
    };

    return {
      label: version.version,
      data: version.id,
      key: version.id!.toString(),
      parent: productNode
    }
  }

  setNodes(inputProductSoftwareVersions: IProjectForNode[]): void {
    inputProductSoftwareVersions.forEach(productSoftwareVersion => this.productSoftwareVersionsNodes.push(this.projectToTreeNode(productSoftwareVersion)));
  }

  setProductSoftwareVersionsSelected(inputProductSoftwareVersions: IProjectForNode[]): void {
    inputProductSoftwareVersions.forEach(project => {
      project.products!.forEach(product => {
        product.versions!.forEach(version => {
          this.productSoftwareVersionsSelected.push(this.selectedVersionToTreeNode(project, product, version));
        })
      })
    });
  }

component.html:

          <p-treeSelect [(ngModel)]="productSoftwareVersionsSelected" display="chip" [metaKeySelection]="false" 
          [ngModelOptions]="{standalone: true}" data-cy="productSoftwareVersion" name="productSoftwareVersion" 
          selectionMode="multiple" id="field_productSoftwareVersion" class="pl-0" type="productSoftwareVersion" 
          aria-describedby="productSoftwareVersion-help" [options]="productSoftwareVersionsNodes" 
          (onNodeUnselect)="nodeUnselected($event)" (onNodeSelect)="nodeSelected($event)">
          </p-treeSelect>

i构建的节点类型:

[{ data: "62bbf3bc16403b596805f6ff"
  key: "62bbf3bc16403b596805f6ff"
  label: "1.2.3"
  parent: {
    data: "TEST"
    expanded: true
    key: "TEST"
    label: "TEST"
    parent: {
      data: "TEST2"
      expanded: true
      icon: "flag-icon flag-icon-gb"
      key: "TEST2"
      label: "TEST2"
      partialSelected: true
    }
    selectable: false
    partialSelected: true
    selectable: false
  }
}]

从单击上选择的节点中的数据:

[{ data: "62bbf3d816403b596805f701"
  key: "62bbf3d816403b596805f701"
  label: "1.2.4"
  parent: {
    children: (3) [{…}, {…}, {…}]
    data: "TEST"
    expanded: true
    key: "TEST"
    label: "TEST"
    parent: {
      children: (3) [{…}, {…}, {…}]
      data: "TEST2"
      expanded: true
      icon: "flag-icon flag-icon-gb"
      key: "TEST2"
      label: "TEST2"
      parent: undefined
      selectable: false
    }
    selectable: false
  }
}]

如果有人有想法...谢谢!

I have a problem in a edit form with PrimeNG Tree or TreeSelect component (I tried both). The thing is data are provided by an API in the form of entity with an ID, a project, a product and a version. In theory, a project can contains many products and a product can contains many versions (this is why I display in tree). So I transform datas from API in a node model. For the creation form, no problem, but for the edit form, impossible to display preselected datas efficiently. The best I can do is the last childrens (versions) are selected but not parents and parents are not expanded.

component.ts :

  productSoftwareVersionsNodes: TreeNode[] = [];
  productSoftwareVersionsSelected: TreeNode[] = [];

  versionToTreeNode(version: IVersionForNode): TreeNode {
    return {
      label: version.version,
      data: version.id,
      key: version.id!.toString()
    }
  }

  productToTreeNode(product: IProductForNode, project: IProjectForNode): TreeNode {
    const versionsNodes: TreeNode[] = [];

    if(product.versions !== undefined){
      product.versions.forEach(version => versionsNodes.push(this.versionToTreeNode(version)));
    }

    return {
      label: product.product,
      key: project.project + "_" + product.product,
      selectable: false,
      data: product.product,
      children: versionsNodes
    }
  
  }

  projectToTreeNode(project: IProjectForNode): TreeNode {

    const productsNodes: TreeNode[] = [];

    if(project.products !== undefined){
      project.products.forEach(product => productsNodes.push(this.productToTreeNode(product, project)));
    }

    return {
      label: project.project,
      data: project.project,
      key: project.project,
      selectable: false,
      // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
      icon: 'flag-icon flag-icon-' + project.countryCode,
      children: productsNodes
    }
    
  }

  selectedVersionToTreeNode(project: IProjectForNode, product: IProductForNode,version: IVersionForNode): TreeNode {

    const projectNode: TreeNode = {
      label: project.project,
      data: project.project,
      key: project.project,
      selectable: false,
      expanded: true,
      partialSelected: true,
      // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
      icon: 'flag-icon flag-icon-' + project.countryCode
    };

    const productNode: TreeNode = {
      label: product.product,
      data: product.product,
      key: project.project + "_" + product.product,
      selectable: false,
      expanded: true,
      partialSelected: true,
      parent: projectNode
    };

    return {
      label: version.version,
      data: version.id,
      key: version.id!.toString(),
      parent: productNode
    }
  }

  setNodes(inputProductSoftwareVersions: IProjectForNode[]): void {
    inputProductSoftwareVersions.forEach(productSoftwareVersion => this.productSoftwareVersionsNodes.push(this.projectToTreeNode(productSoftwareVersion)));
  }

  setProductSoftwareVersionsSelected(inputProductSoftwareVersions: IProjectForNode[]): void {
    inputProductSoftwareVersions.forEach(project => {
      project.products!.forEach(product => {
        product.versions!.forEach(version => {
          this.productSoftwareVersionsSelected.push(this.selectedVersionToTreeNode(project, product, version));
        })
      })
    });
  }

component.html :

          <p-treeSelect [(ngModel)]="productSoftwareVersionsSelected" display="chip" [metaKeySelection]="false" 
          [ngModelOptions]="{standalone: true}" data-cy="productSoftwareVersion" name="productSoftwareVersion" 
          selectionMode="multiple" id="field_productSoftwareVersion" class="pl-0" type="productSoftwareVersion" 
          aria-describedby="productSoftwareVersion-help" [options]="productSoftwareVersionsNodes" 
          (onNodeUnselect)="nodeUnselected($event)" (onNodeSelect)="nodeSelected($event)">
          </p-treeSelect>

The kind of node I build :

[{ data: "62bbf3bc16403b596805f6ff"
  key: "62bbf3bc16403b596805f6ff"
  label: "1.2.3"
  parent: {
    data: "TEST"
    expanded: true
    key: "TEST"
    label: "TEST"
    parent: {
      data: "TEST2"
      expanded: true
      icon: "flag-icon flag-icon-gb"
      key: "TEST2"
      label: "TEST2"
      partialSelected: true
    }
    selectable: false
    partialSelected: true
    selectable: false
  }
}]

Data from a node selected on click:

[{ data: "62bbf3d816403b596805f701"
  key: "62bbf3d816403b596805f701"
  label: "1.2.4"
  parent: {
    children: (3) [{…}, {…}, {…}]
    data: "TEST"
    expanded: true
    key: "TEST"
    label: "TEST"
    parent: {
      children: (3) [{…}, {…}, {…}]
      data: "TEST2"
      expanded: true
      icon: "flag-icon flag-icon-gb"
      key: "TEST2"
      label: "TEST2"
      parent: undefined
      selectable: false
    }
    selectable: false
  }
}]

If someone has an idea... Thanks !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溺ぐ爱和你が 2025-02-18 14:07:57

我找到了解决方案。关键是在选项中使用节点并过滤它们:

  // Preselect nodes for the editForm
  setProductSoftwareVersionsSelected(productSoftwareVersionsList: IProductSoftwareVersion[]): void {
    // Get all productSoftwareVersions id from the editForm in an array
    const productSoftwareVersionIdList: string[]= productSoftwareVersionsList.flatMap(p => p.id?.toString()) as string[];

    // Set the selected nodes by filtering all nodes with the array of ids
    this.productSoftwareVersionsSelected = this.productSoftwareVersionsNodes.flatMap(n => n.children).flatMap(c => c?.children).filter(v => v?.key !== undefined && productSoftwareVersionIdList.includes(v.key)) as TreeNode[];
  }

I found solution. The key is to work with nodes in options and filter them:

  // Preselect nodes for the editForm
  setProductSoftwareVersionsSelected(productSoftwareVersionsList: IProductSoftwareVersion[]): void {
    // Get all productSoftwareVersions id from the editForm in an array
    const productSoftwareVersionIdList: string[]= productSoftwareVersionsList.flatMap(p => p.id?.toString()) as string[];

    // Set the selected nodes by filtering all nodes with the array of ids
    this.productSoftwareVersionsSelected = this.productSoftwareVersionsNodes.flatMap(n => n.children).flatMap(c => c?.children).filter(v => v?.key !== undefined && productSoftwareVersionIdList.includes(v.key)) as TreeNode[];
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文