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

Angular中分类组件与卡片组件的筛选联动实现方案问询

Angular分类组件与卡片组件联动实现方案

最常用的方案是通过共享服务实现跨组件通信,这种方式适合无父子关系的独立组件,能高效实现分类选择与卡片筛选的联动。以下是具体实现步骤:

1. 创建共享筛选服务

创建一个全局注入的FilterService,用来管理选中的分类状态,并通过Observable通知订阅组件状态变化:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class FilterService {
  // BehaviorSubject保存当前选中分类,初始值设为空表示默认显示全部
  private selectedCategory$ = new BehaviorSubject<string>('');
  // 对外暴露Observable,避免外部直接修改状态
  currentCategory$: Observable<string> = this.selectedCategory$.asObservable();

  // 更新选中分类的方法
  updateSelectedCategory(category: string): void {
    this.selectedCategory$.next(category);
  }

  // 获取当前选中分类(可选,用于组件内状态判断)
  getCurrentCategory(): string {
    return this.selectedCategory$.value;
  }
}

2. 修改CategoriesList组件

注入FilterService,在用户点击分类时调用服务方法更新选中状态:

import { Component } from '@angular/core';
import { FilterService } from '../services/filter.service';

@Component({
  selector: 'app-categories-list',
  templateUrl: './categories-list.component.html',
  styleUrls: ['./categories-list.component.css']
})
export class CategoriesListComponent {
  // 示例分类列表,可根据实际业务从接口获取
  categories: string[] = ['科技', '生活', '娱乐', '美食'];

  constructor(private filterService: FilterService) {}

  // 分类点击事件
  onCategoryClick(category: string): void {
    this.filterService.updateSelectedCategory(category);
  }
}

对应的组件模板(添加选中状态样式):

<div class="category-group">
  <button 
    *ngFor="let category of categories"
    (click)="onCategoryClick(category)"
    [class.active]="category === filterService.getCurrentCategory()"
  >
    {{ category }}
  </button>
  <!-- 可选:添加"全部"选项 -->
  <button 
    (click)="onCategoryClick('')"
    [class.active]="filterService.getCurrentCategory() === ''"
  >
    全部
  </button>
</div>

3. 修改Card组件

注入FilterService和AuthService,订阅分类状态变化,实时筛选卡片数据:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { FilterService } from '../services/filter.service';
import { AuthService } from '../services/auth.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  styleUrls: ['./card.component.css']
})
export class CardComponent implements OnInit, OnDestroy {
  originalCards: any[] = [];
  filteredCards: any[] = [];
  private categorySub: Subscription | undefined;

  constructor(
    private authService: AuthService,
    private filterService: FilterService
  ) {}

  ngOnInit(): void {
    // 从AuthService获取原始卡片数据(假设AuthService提供getCards方法)
    this.authService.getCards().subscribe(cards => {
      this.originalCards = cards;
      // 初始化筛选结果
      this.filterCards(this.filterService.getCurrentCategory());
    });

    // 订阅分类变化,实时更新筛选结果
    this.categorySub = this.filterService.currentCategory$.subscribe(category => {
      this.filterCards(category);
    });
  }

  // 筛选逻辑
  private filterCards(category: string): void {
    if (!category) {
      // 分类为空时显示全部卡片
      this.filteredCards = [...this.originalCards];
    } else {
      // 根据选中分类筛选卡片
      this.filteredCards = this.originalCards.filter(card => card.category === category);
    }
  }

  // 组件销毁时取消订阅,避免内存泄漏
  ngOnDestroy(): void {
    this.categorySub?.unsubscribe();
  }
}

对应的组件模板:

<div class="card-container">
  <div *ngFor="let card of filteredCards" class="card-item">
    <!-- 卡片内容渲染,示例: -->
    <h3>{{ card.title }}</h3>
    <p>{{ card.description }}</p>
    <span class="category-tag">{{ card.category }}</span>
  </div>
</div>

可选方案说明

  • 如果组件存在父子关系,也可以通过@Input传递筛选条件、@Output触发筛选事件,但独立组件间用共享服务更灵活。
  • 若需要路由同步筛选状态,可以结合Router传递分类参数,但服务方式更轻量,适合不需要路由变化的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:31:01