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

Angular中如何基于API返回的图片名去重渲染图片?

看起来你是想解决Angular中渲染部件图片时重复显示的问题——因为多个部件共享同一张图,现在用*ngFor遍历所有数据导致同一张图重复出现。我看了你在filterDrop里尝试的排序逻辑,其实那不是正确的去重方式(sort是用来排序的,而且你在sort里创建的局部数组根本没法保存去重后的结果),下面给你几个实用的实现思路和代码方案:

方案一:仅在图片首次出现时显示(保留原有行结构)

如果你想保留原来的每行一个部件的结构,但相同图片只在第一次出现时显示,后续行隐藏图片,可以这样做:

  1. 在组件中给每个部件添加显示标记
    在filterDrop方法里,用Set跟踪已经出现过的图片,给每个部件对象增加一个showImage属性,标记是否需要显示图片:

    filterDrop() {
      this.dataDiam1 = this.dataDynParts;
      let dynDiam1 = this.dataDiam1.map(obj => obj.diam[0]);
      dynDiam1 = dynDiam1.filter((v, i) => dynDiam1.indexOf(v) === i);
      this.dataDiam1 = dynDiam1;
    
      this.dataDiam2 = this.dataDynParts;
      let dynDiam2 = this.dataDiam2.map(obj => obj.diam[1]);
      dynDiam2 = dynDiam2.filter((v, i) => dynDiam2.indexOf(v) === i);
      this.dataDiam2 = dynDiam2;
    
      this.requiredFields();
      this.filteredWithDiam = this.dataDynParts;
    
      // 新增:处理图片显示标记
      const seenImages = new Set<string>();
      this.selectedDiam = this.dataDynParts.map(item => {
        const showImage = !seenImages.has(item.part_image);
        if (showImage) {
          seenImages.add(item.part_image);
        }
        // 扩展原对象,添加showImage属性
        return { ...item, showImage };
      });
    }
    
  2. 在模板中根据标记控制图片显示
    修改HTML里的img标签,用*ngIf判断是否显示:

    <div class="products">
      <div class="d-flex flex-row linesColor" *ngFor="let products of selectedDiam">
        <img *ngIf="products.showImage" [src]="photosPath + products.part_image" alt="部件图片">
        <a class="flex1">{{products.diam}}</a>
        <a class="flex1">{{products.price1}}</a>
        <a class="flex1 mb-1">
          <input [ngModel]="products.longueur" (ngModelChange)="postQuotationDatas($event,products,'longueur')" class="number" type="number">
        </a>
        <a class="flex1">Total</a>
      </div>
    </div>
    

方案二:按图片分组渲染(图片仅显示一次,下方列出对应所有部件)

如果你想更清晰地组织视图——同一张图片只显示一次,下面列出所有使用该图片的部件,可以按图片分组:

  1. 在组件中按图片分组数据
    新增一个groupedParts数组,用来存储分组后的图片和对应部件:

    // 组件类中新增属性
    groupedParts: { image: string, parts: any[] }[] = [];
    
    filterDrop() {
      // ... 保留你原来的其他代码
    
      // 新增:按part_image分组数据
      const imageGroups: { [key: string]: any[] } = {};
      this.dataDynParts.forEach(part => {
        const imgKey = part.part_image;
        // 处理空图片的情况,避免无意义分组
        if (!imgKey) return;
        if (!imageGroups[imgKey]) {
          imageGroups[imgKey] = [];
        }
        imageGroups[imgKey].push(part);
      });
      // 转换为数组格式,方便模板遍历
      this.groupedParts = Object.entries(imageGroups).map(([image, parts]) => ({ image, parts }));
    }
    
  2. 在模板中渲染分组后的内容
    先渲染图片,再遍历该图片对应的所有部件:

    <div class="products">
      <!-- 遍历每个图片组 -->
      <div *ngFor="let group of groupedParts">
        <!-- 显示一次图片 -->
        <div class="d-flex flex-row linesColor">
          <img [src]="photosPath + group.image" alt="部件图片">
          <a class="flex1">对应部件列表</a>
        </div>
        <!-- 显示该图片下的所有部件 -->
        <div class="d-flex flex-row linesColor" *ngFor="let product of group.parts">
          <a class="flex1">{{product.diam}}</a>
          <a class="flex1">{{product.price1}}</a>
          <a class="flex1 mb-1">
            <input [ngModel]="product.longueur" (ngModelChange)="postQuotationDatas($event,product,'longueur')" class="number" type="number">
          </a>
          <a class="flex1">Total</a>
        </div>
      </div>
    </div>
    

方案三:直接生成去重的图片数组(仅渲染图片,不关联部件)

如果你只需要单独渲染所有不重复的图片,不需要和部件关联,可以直接生成去重的图片数组:

// 组件类中新增属性
uniquePhotos: string[] = [];

filterDrop() {
  // ... 保留你原来的其他代码

  // 生成去重的图片数组,过滤空值
  this.uniquePhotos = [...new Set(this.dataDynParts.map(item => item.part_image))].filter(img => img);
}

模板中遍历这个数组:

<div class="products">
  <div class="d-flex flex-row linesColor" *ngFor="let photo of uniquePhotos">
    <img [src]="photosPath + photo" alt="部件图片">
  </div>
</div>

小提示

  • 确保part_image字段的值是准确的(比如没有大小写差异、空格等,否则Set会认为是不同的图片),如果有格式问题,可以在map的时候统一处理(比如item.part_image.trim().toLowerCase())。
  • 如果你用的是Angular 14+,可以考虑用trackBy优化*ngFor的性能,避免不必要的DOM重渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:47:51