Angular数据过滤:仅显示包含发布内容的分类(Rails示例参考)
Got it, let's break down how to implement this filtering logic—just like the category.posts check you're used to in Rails. I'll walk you through step-by-step with your sample data.
First, Let's Tidy Up the Data Structure
Your raw category data is a bit nested ([{"Cortes":{"name":"Cortes"}, "peinados":{"name":"peinados"}}]), so first we'll convert it into a more workable array. This makes filtering easier later on.
In your component TypeScript file:
// Raw data from your API rawCategories = [{"Cortes":{"name":"Cortes"}, "peinados":{"name":"peinados"}}]; posts = [{"category": "Cortes","title": "first"}]; // Convert categories to a flat array with ID and name categories = Object.entries(this.rawCategories[0]).map(([id, category]) => ({ id, name: category.name }));
Option 1: Filter Directly in the Component
Create a method to return only categories that have associated posts. This mimics the Rails category.posts.present? check:
getActiveCategories() { // Grab all category IDs that are used in posts const usedCategoryIds = this.posts.map(post => post.category); // Filter categories to only those with IDs in the used list return this.categories.filter(category => usedCategoryIds.includes(category.id)); }
Then use this method in your template to render the filtered categories:
<h2>Categories with Published Content</h2> <ul> <li *ngFor="let category of getActiveCategories()"> {{ category.name }} </li> </ul>
Option 2: Use a Reusable Angular Pipe (For Multiple Components)
If you need this filtering logic in multiple places, a custom pipe is cleaner. Create a new pipe file (e.g., category-with-posts.pipe.ts):
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'categoryWithPosts' }) export class CategoryWithPostsPipe implements PipeTransform { transform(rawCategories: {[key: string]: {name: string}}, posts: {category: string}[]) { const usedIds = posts.map(post => post.category); // Convert raw category object to array and filter return Object.entries(rawCategories) .filter(([id]) => usedIds.includes(id)) .map(([id, category]) => ({ id, name: category.name })); } }
Don't forget to declare this pipe in your Angular module, then use it directly in your template:
<h2>Categories with Published Content</h2> <ul> <li *ngFor="let category of rawCategories[0] | categoryWithPosts: posts"> {{ category.name }} </li> </ul>
How This Works
Both approaches do the same core thing:
- Collect all category IDs that are linked to existing posts
- Filter out any categories whose IDs aren't in that list
- Only render the categories that have at least one associated post
This replicates the exact logic you'd use in Rails with category.posts, but adapted to Angular's data handling.
内容的提问来源于stack exchange,提问作者Carlos Uriel Santiago

