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

Angular中基于复选框实现二级过滤的技术求助

实现支持搜索+标签二级过滤的Angular管道

1. 改造现有FilterPipe,支持多条件过滤

直接扩展你现有的管道,让它同时接收搜索关键词和选中的标签数组,依次完成两级过滤:

import { Pipe, PipeTransform } from '@angular/core';
import { Recipe } from './your-recipe.model'; // 替换为你的Recipe模型路径

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {
  transform(
    recipes: Recipe[],
    searchValue: string = '',
    selectedTags: string[] = []
  ): Recipe[] {
    if (!recipes?.length) return [];

    // 第一级:标题/食材搜索过滤(忽略大小写,去重)
    const lowerSearch = searchValue.toLowerCase().trim();
    const searchFiltered = new Set<Recipe>();

    for (const recipe of recipes) {
      // 匹配标题
      if (recipe.title.toLowerCase().includes(lowerSearch)) {
        searchFiltered.add(recipe);
        continue;
      }
      // 匹配食材名称
      const hasMatchIngredient = recipe.ingredients.some(ing => 
        ing.name.toLowerCase().includes(lowerSearch)
      );
      if (hasMatchIngredient) searchFiltered.add(recipe);
    }

    let result = Array.from(searchFiltered);

    // 第二级:标签过滤(仅当有选中标签时执行)
    if (selectedTags.length > 0) {
      result = result.filter(recipe => {
        // 检查食谱标签是否包含任意一个选中标签(忽略大小写)
        return recipe.tags.some(tag => 
          selectedTags.some(selected => 
            tag.toLowerCase() === selected.toLowerCase()
          )
        );
      });
    }

    return result;
  }
}

2. 模板与组件逻辑调整

组件内新增标签相关变量与方法

// 组件.ts文件
selectedTags: string[] = [];
allTags: string[] = ['素食', '快餐', '烘焙', '中式']; // 替换为你的全量标签列表

onTagToggle(event: Event, tag: string) {
  const checkbox = event.target as HTMLInputElement;
  if (checkbox.checked) {
    this.selectedTags.push(tag);
  } else {
    this.selectedTags = this.selectedTags.filter(t => t !== tag);
  }
}

模板中添加复选框与更新过滤管道调用

<!-- 标签过滤复选框区域 -->
<div class="tag-filters mb-3">
  <label *ngFor="let tag of allTags" class="me-3">
    <input 
      type="checkbox" 
      [value]="tag" 
      (change)="onTagToggle($event, tag)"
    >
    {{ tag }}
  </label>
</div>

<!-- 过滤后的食谱展示 -->
<div *ngIf="recipesArr | filter: recipeName: selectedTags as filteredRecipes">
  <div class="d-flex gap-4 flex-wrap">
    <div class="card" *ngFor="let recipe of filteredRecipes">
      <!-- 原有卡片内容保持不变 -->
      <div (click)="likeRecipe(recipe.recipe_id!)" class="overlay" [ngClass]="{'already-liked': checkIfThisRecipeIsLiked(recipe.recipe_id!)}">
        <i class="fa-solid fa-star mx-3 favorite"></i>
      </div>
      
      <img [src]="recipe.img" class="cardImg" />
      <div class="m-1">
        <div class="card-titles">{{ recipe.title }}</div>
        <div class="card-text small mb-2">
          包含 {{ recipe.ingredients.length }} 种食材
        </div>
      </div>
    </div>
  </div>
</div>

核心说明

  • 管道会先完成搜索过滤,再根据选中的标签进一步缩小结果;如果没有选中标签,直接返回搜索结果
  • 加入了忽略大小写的处理,提升搜索体验
  • 用Set处理搜索过滤避免重复添加同一食谱
  • 复选框的change事件实时更新selectedTags数组,Angular会自动触发管道重新执行过滤

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:30:51