如何在primeng自动完成角度8中对建议嵌套列表进行分组

2024-04-24

我正在尝试对自动完成建议进行分组,并希望在 primeng 中呈现它们。

我们如何在primeng中添加自定义模板?

my data

data = [{"id":"m1","name":"menu1","val":"D","items":[{"id":"d1","name":"datanested1","val":"D","items":[{"id":"1","name":"direct Data","val":"E"},{"id":"2","name":"test","val":"E"}]}]},{"id":"d2","name":"menu2","val":"D","items":[{"id":"21","name":"test21","val":"E"},{"id":"22","name":"test23","val":"E"}]},{"id":"d3","name":"menu3","val":"D","items":[{"id":"31","name":"test data 3","val":"E"},{"id":"32","name":"test data 4","val":"E"}]}]

Angular 8 中是否有其他库支持此功能?

当用户开始在自动完成中搜索时,我想实现这样的目标......

Menu1 - header
 datanested1 -subheader
  direct Data -values
   test        -values

Menu2 - header
 test21-values
 test23-values

Menu3 - header
 test data 3-values
 test data 4-values


1. if the user types "direct" in the input box...

Menu1 - header
 datanested1 -subheader
  direct Data -values

2. if the user types "data" in the input box...

Menu3 - header
 test data 3-values
 test data 4-values

3. if the user types "menu" in the input box...
Menu1 - header
 datanested1 -subheader
  direct Data -values
  test        -values

Menu2 - header
 test21-values
 test23-values

Menu3 - header
 test data 3-values
 test data 4-values

我在 stackblitz 中尝试了以下示例。

https://stackblitz.com/edit/primeng-7-1-2-qtsnpm https://stackblitz.com/edit/primeng-7-1-2-qtsnpm


在下面的方法中,我们将数组简化为简单的结构

[
  {
    "id": "m1",
    "name": "menu1",
    "val": "D",
    "search": ["m1", "d1", "1", "2", "menu1", "datanested1", "direct Data", "test"],
    "depth": 2
  },
  {
    "id": "d1",
    "name": "datanested1",
    "val": "D",
    "search": ["d1", "1", "2", "datanested1", "direct Data", "test"],
    "depth": 1
  },
  {
    "id": "1",
    "name": "direct Data",
    "val": "E",
    "search": ["1", "direct Data"
    ],
    "depth": 0
  },
 ...

]

想法是这样的,我们将使用depth格式化文本,同时search用于搜索。

  maxDepth = 0;
  reducedArray = (arr, depth = 0, parentSearch = []) => {
    this.maxDepth = Math.max(this.maxDepth, depth);
    if (!arr) {
      return [];
    }

    return arr.reduce((prev, { items, ...otherProps }) => {
      // const depth = this.findDepth({ items, ...otherProps });
      const search = [
        ...this.getProps({ items, ...otherProps }, "id"),
        ...this.getProps({ items, ...otherProps }, "name")
      ];
      const newParentSearch = [...parentSearch, otherProps.name, otherProps.id];
      return [
        ...prev,
        { ...otherProps, search, depth, parentSearch },
        ...this.reducedArray(items, depth + 1, newParentSearch)
      ];
    }, []);
  };

  getProps = (item, prop) => {
    if (!item.items) {
      return [item[prop]];
    } else {
      return [
        item[prop],
        ...item.items.map(x => this.getProps(x, prop))
      ].flat();
    }
  };

我们可以应用如下所示的样式

  getStyle(depth) {
    return {
      color: depth === 0 ? "darkblue" : depth === 1 ? "green" : "black",
      paddingLeft: depth * 7 + "px",
      fontWeight: 800 - depth * 200
    };
  }

我将使用响应式编程,因此我将使用以下方法将对象转换为 Observableof操作员

  data$ = of(this.reducedArray(this.data));
  filteredData$ = combineLatest([this.data$, this.filterString$]).pipe(
    map(([data, filterString]) =>
      data.filter(
        ({ search, parentSearch }) =>
          !![...search, ...parentSearch].find(x => x.includes(filterString))
      )
    )
  );

现在我们已经完成了,剩下的就是更新html了

<p-autoComplete [(ngModel)]="cdsidvalue" [suggestions]="filteredData$ | async"
  (completeMethod)="filterString$.next($event.query)" field="name" [size]="16" placeholder="Menu" [minLength]="1">
  <ng-template let-menu pTemplate="item">
    <span 
      [ngStyle]="getStyle(menu.depth)" >{{ menu.name }}</span>
  </ng-template>

</p-autoComplete>

演示在这里 https://stackblitz.com/edit/primeng-7-1-2-pofce9?file=src%2Fapp%2Fapp.component.ts

Update

由于我们使用反应式编程,重构以接受 http 请求非常容易,只需用 http 请求替换 observable

data$ = this.http.get<any[]>("my/api/url");
  filteredData$ = combineLatest([this.data$, this.filterString$]).pipe(
    map(([data, filterString]) =>
      this.reducedArray(data).filter(
        ({ search, parentSearch }) =>
          !![...search, ...parentSearch].find(x => x.includes(filterString))
      )
    )
  );

查看此更新的实际效果 https://stackblitz.com/edit/primeng-7-1-2-y9ggte?file=src%2Fapp%2Fapp.component.ts

我还更新了 html 以添加加载消息,我们不想显示没有数据的表单

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在primeng自动完成角度8中对建议嵌套列表进行分组 的相关文章

  • 带有 nx 测试的 Angular v13 Jest - SyntaxError:无法在 Runtime.createScriptFromCode 的模块外部使用 import 语句

    我尝试用可能的解决方案来关注每条评论here https github com nrwl nx issues 7844至此 我还依赖 github 上的一个示例项目 它运行得很好 在手动更新所有内容之后 这也开始发生在我身上 并且在运行 n
  • Jhipster 生成器跳过 --skip-server 处的身份验证代码

    为什么当我们使用 skip server 生成项目时 哟 jhipster skip server 部分身份验证丢失 在 AJS A2 上 是吗 每次我需要粘贴部分代码 Angular 上的 AuthServerProvider 或 Ang
  • Angular 2 SPA Azure Active Directory JWT 问题

    想知道是否有 Azure Active Directory Angular 2 Adal 专家可以提供帮助 我的设置如下 具有三个应用程序注册的 Azure Active Directory 一种用于 Web API 一种用于 WPF 应用
  • 图像下方不需要的边距

    我有一个图像和一个 div 我想将其放置在其下方 这是小提琴 http jsfiddle net d3Mne 1 http jsfiddle net d3Mne 1 问题是两者之间存在差距 此下边距仅出现在图像中 有什么办法可以去除吗 Se
  • 选中复选框时展开 Div

    我有一个复选框
  • 等待网页完全加载,然后再使用 python 请求进行抓取

    我目前正在尝试从 LinkedIn 上的特定页面抓取数据 我有一个能够登录 LinkedIn 的脚本 但当我尝试访问包含数据的页面时遇到了障碍 当我打电话时requests get data url 我最终得到了 LinkedIn 加载屏幕
  • 交替 div 使图像向左(偶数)或向右(奇数)

    我正在尝试更好地排列图像 而不仅仅是一列中的图像 请参阅附件中的示例 每篇文章的图像可以位于左侧和右侧 这是我的代码 HTML section class content list page section
  • JavaScript 跨浏览器单击 HTML DOM 元素

    是否有可用的普通 JavaScript 跨浏览器函数能够触发 HTML DOM 元素 包括 div 等非表单元素 上的单击事件 大多数走这条路的人要么最终开发自己的事件管理系统 这并不难 但很烦人 要么在可用的功能范围内工作 如果所有浏览器
  • 如何防止 this.debug is not a function 导致编译器退出

    参考这里提出的问题this debug 不是 Angular 通用函数 https stackoverflow com questions 65966642 this debug is not a function angular univ
  • iFrame 未扩展至 100% 高度

    我有这个下面的html 我希望 iFrame 能够 100 覆盖屏幕的其余部分 我在高度属性中尝试了 100 和 但不起作用 这是为什么 谢谢 div img height 35 width 84 alt Kucku src Content
  • 动态表中每个按钮的 Jquery-Ui 对话框表单

    我正在生成一个 HTML 表 每行都有一个按钮 必须打开 Jquery ui 对话框表单 The table table class table table reporting table condensed table striped t
  • 显示带有背景颜色的百分比条

    例如 如果我有一个包含两列和 2 行的表 Col1 Percentage 50 50 70 70 如何用代表 COl1 值的颜色填充百分比列 像这样的东西 您可以使用具有两个紧接着的停止点的线性渐变 percentageFill heigh
  • 在 IE10 中禁用捏合放大

    在 IE10 触摸模式下 我希望仅使页面的特定部分可缩放 其余的不应该 我找到了这个 http msdn microsoft com en US library ie hh772044 aspx http msdn microsoft co
  • 单击输入字段会触发窗口调整大小

    我有一个带有徽标 菜单和搜索的标题 当我在桌面上时 我会按该顺序显示所有元素 但如果我的窗口宽度小于 980 像素 菜单会隐藏 有一个切换按钮 并且徽标会与nav并附在徽标之后 如果宽度更大 则徽标将再次分离并附加到 DOM 中的旧位置 w
  • 表单提交后 Angular2 更新视图

    我正在使用 Angular2 创建一个简单的 CRUD 应用程序 该应用程序由一个列出当前记录的表格和一个用于提交新记录的表格组成 提交表单后更新表格以反映新记录的正确方法是什么 这是我到目前为止所拥有的 export class Pers
  • 如何在 div 容器内的元素之间留出空间

    我有一个弹性容器 它将由元素动态填充 容器没有固定宽度 I use max width max content 并且可以包含我想要的任意数量的元素 问题是我需要这些元素之间的间距 但不需要元素和容器之间左侧和右侧的间距 当然我可以用 ele
  • 显示班级图片 10 秒

    我有下面给出的代码显示9 boxes 其值如下digital time 还有一个班级box002显示digits相当于随机选择的九个盒子的值 box002 can be dragged to digital time starting wi
  • 如何修复 getImageData() 错误画布已被跨源数据污染?

    我的代码在本地主机上运行得很好 但在网站上却不起作用 我从控制台收到此错误 对于这一行 getImageData x y 1 1 data Uncaught SecurityError Failed to execute getImageD
  • 让登录更安全

    我已使用此代码进行管理员登录 仅当用户输入正确的用户名和密码时才应打开loginhome php 但后来我意识到这根本不安全 任何人都可以直接访问 mywebsite loginhome php 而无需登录 注销后 可以使用后退按钮打开 l
  • 使用 JavaScript onclick 添加表格行

    我正在尝试使用 javascript 添加下面找到的完全相同的元素 我已经尝试了这里找到的所有解决方案 我什至尝试用php echo但没有运气 无需更改任何输入名称或类似内容 只需单击该按钮即可向表中添加另一行 仅此而已 这是该元素 tr

随机推荐