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

Angular4侧边栏Filter Pipe实现女装筛选及选中项展示需求

实现Angular 4侧边栏筛选与选中条件展示

我来帮你完善侧边栏的筛选功能,包含Filter Pipe实现、选中条件展示以及筛选状态管理,一步步来:

1. 创建自定义筛选Pipe

首先需要一个Pipe来处理产品列表的多条件过滤,在项目中新建product-filter.pipe.ts:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'productFilter'
})
export class ProductFilterPipe implements PipeTransform {
  transform(items: any[], filters: any): any[] {
    // 如果没有产品数据或筛选条件,直接返回原列表
    if (!items || !filters) return items;

    // 多条件匹配逻辑:同时满足所有选中的筛选项
    return items.filter(item => {
      let isMatch = true;

      // 颜色筛选匹配
      if (filters.color?.length) {
        isMatch = isMatch && filters.color.includes(item.color);
      }
      // 袖长筛选匹配
      if (filters.sleeve?.length) {
        isMatch = isMatch && filters.sleeve.includes(item.sleeveLength);
      }
      // 尺码筛选匹配
      if (filters.size?.length) {
        isMatch = isMatch && filters.size.includes(item.size);
      }

      return isMatch;
    });
  }
}

记得在app.module.ts的declarations数组中声明这个Pipe,确保Angular能识别它。

2. 组件类中管理筛选状态

修改app.component.ts,添加选中条件的存储对象,以及更新选中状态的方法:

import { Component, OnInit } from '@angular/core';
import { DataserviceService } from './dataservice.service';
import { AppGlobals } from './app-globals';

export class AppComponent implements OnInit {
  constructor(private dataservice:DataserviceService,private global: AppGlobals){}
  
  httpdata: any[] = [];
  colours: any[] = [];
  sleeve: any[] = [];
  length: any[] = [];
  // 存储每个类别的选中条件,用数组支持多选
  selectedFilters = {
    color: [],
    sleeve: [],
    size: []
  };
  icon1 = false;

  ngOnInit() {
    // 注意:你当前sleeve和length的API调用是同一个地址,建议检查是否为对应接口
    this.dataservice.getApparel(this.global.AppUrl +'getRecommendations?client=web&call_tag=stylemachine&size=15&position=0&attempt=0&user=5724&project=2226&collection=200&category=16&client-tag=women_apparels')
      .subscribe(data => this.httpdata = data);
    this.dataservice.getFilter(this.global.AppUrl +'availableFilters?client=web&category=16')
      .subscribe(colours => this.colours = colours);
    this.dataservice.getSleeve(this.global.AppUrl +'availableFilters?client=web&category=16')
      .subscribe(sleeve => this.sleeve = sleeve);
    this.dataservice.getLength(this.global.AppUrl +'availableFilters?client=web&category=16')
      .subscribe(length => this.length = length);
  }

  toggle1() {
    this.icon1 = !this.icon1;
  }

  // 更新选中的筛选条件(支持多选)
  updateFilter(category: string, option: any) {
    const selectedList = this.selectedFilters[category];
    const optionIndex = selectedList.indexOf(option.title);
    
    if (optionIndex > -1) {
      // 已选中则移除
      selectedList.splice(optionIndex, 1);
    } else {
      // 未选中则添加
      selectedList.push(option.title);
    }

    // 如果需要单选逻辑,替换成下面这段:
    // this.selectedFilters[category] = [option.title];
  }

  // 清除单个筛选条件
  removeFilter(category: string, value: string) {
    const index = this.selectedFilters[category].indexOf(value);
    if (index > -1) {
      this.selectedFilters[category].splice(index, 1);
    }
  }

  // 清除所有筛选条件
  clearAllFilters() {
    this.selectedFilters = { color: [], sleeve: [], size: [] };
  }
}

3. 修改模板:添加选中状态与条件展示

更新app.component.html,给筛选选项添加选中样式,绑定点击事件,同时增加选中条件的展示面板:

<div class="col-md-6" id="sidebar">
  <!-- 选中条件展示区域 -->
  <div class="selected-filters p-3 mb-4 bg-light rounded">
    <span class="fw-bold">已选条件:</span>
    <!-- 颜色选中标签 -->
    <span 
      *ngFor="let color of selectedFilters.color" 
      class="badge bg-primary me-2"
    >
      {{color}} <span (click)="removeFilter('color', color)" class="ms-1 text-white cursor-pointer">&times;</span>
    </span>
    <!-- 袖长选中标签 -->
    <span 
      *ngFor="let sleeve of selectedFilters.sleeve" 
      class="badge bg-primary me-2"
    >
      {{sleeve}} <span (click)="removeFilter('sleeve', sleeve)" class="ms-1 text-white cursor-pointer">&times;</span>
    </span>
    <!-- 尺码选中标签 -->
    <span 
      *ngFor="let size of selectedFilters.size" 
      class="badge bg-primary me-2"
    >
      {{size}} <span (click)="removeFilter('size', size)" class="ms-1 text-white cursor-pointer">&times;</span>
    </span>
    <!-- 清除全部按钮 -->
    <button 
      *ngIf="Object.values(selectedFilters).some(list => list.length > 0)"
      class="btn btn-sm btn-outline-danger ms-2"
      (click)="clearAllFilters()"
    >
      清除全部
    </button>
  </div>

  <ul class="nav">
    <!-- 颜色筛选菜单 -->
    <li class="nav-item">
      <a 
        class="nav-link" 
        routerLink="#submenu" 
        data-toggle="collapse" 
        (click)="toggle1()" 
        data-target="#submenu"
      >
        Color 
        <mat-icon class="pull-right">{{icon1 ? 'remove' : 'add' }}</mat-icon>
      </a>
      <div class="collapse" id="submenu" aria-expanded="false">
        <ul class="nav" *ngFor="let colour of colours">
          <li class="nav-item">
            <a 
              class="nav-link" 
              [class.active]="selectedFilters.color.includes(colour.title)"
              (click)="updateFilter('color', colour); $event.preventDefault()"
            >
              {{colour.title}}
            </a>
          </li>
        </ul>
      </div>
    </li>

    <!-- 袖长筛选菜单 -->
    <li class="nav-item">
      <a 
        class="nav-link" 
        routerLink="#submenu2" 
        data-toggle="collapse" 
        data-target="#submenu2"
      >
        sleeve-length 
        <mat-icon class="pull-right">add</mat-icon>
      </a>
      <div class="collapse" id="submenu2" aria-expanded="false">
        <ul class="nav" *ngFor="let s of sleeve">
          <li class="nav-item">
            <a 
              class="nav-link" 
              [class.active]="selectedFilters.sleeve.includes(s.title)"
              (click)="updateFilter('sleeve', s); $event.preventDefault()"
            >
              {{s.title}}
            </a>
          </li>
        </ul>
      </div>
    </li>

    <!-- 尺码筛选菜单 -->
    <li class="nav-item">
      <a 
        class="nav-link" 
        routerLink="#submenu3" 
        data-toggle="collapse" 
        data-target="#submenu3"
      >
        sizes
        <mat-icon class="pull-right">add</mat-icon>
      </a>
      <div class="collapse" id="submenu3" aria-expanded="false">
        <ul class="nav" *ngFor="let size of length">
          <li class="nav-item">
            <a 
              class="nav-link" 
              [class.active]="selectedFilters.size.includes(size.title)"
              (click)="updateFilter('size', size); $event.preventDefault()"
            >
              {{size.title}}
            </a>
          </li>
        </ul>
      </div>
    </li>
  </ul>
</div>

<!-- 产品列表应用筛选Pipe -->
<div class="col-sm-6 col-md-4" *ngFor="let x of httpdata | productFilter: selectedFilters; let i = index">
  <div class="panel panel-default">
    <div class="panel-body">
      <img src="{{x.product_image}}" height="300px" width="200px">
      <!-- 可添加产品其他信息 -->
      <h6 class="mt-2">{{x.product_name}}</h6>
      <p>颜色:{{x.color}}</p>
      <p>袖长:{{x.sleeveLength}}</p>
    </div>
  </div>
</div>

几点注意事项

  • 修正了原代码中的routerlink为Angular规范的驼峰写法routerLink,并添加$event.preventDefault()防止点击筛选项时触发路由跳转。
  • 筛选Pipe中的字段匹配(如item.color)需要和你的产品数据结构对应,如果字段名不一致请自行调整。
  • 当前实现的是多选逻辑,如果需要单选,只需把updateFilter方法中的替换注释部分的代码即可。
  • 你当前调用袖长和尺码的API地址相同,建议检查是否为正确的接口地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:29:38