Angular矿物买卖应用:按BuySell字段拆分矿物列表求助
Hey there! Let's work through getting your Angular mineral trading app set up exactly how you want it. I’ve looked over your code and spotted a few tweaks we need to make to get the mineral filtering working correctly across your different sections.
1. Fix the Mineral Service Data Handling
First, I noticed your minerals.json is an array, but your service is using for...in to iterate over it (which is meant for objects, not arrays). Let's rewrite the service method to use array filtering, and make it flexible enough to return empty arrays for your home and news sections:
// mineral-world.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { map } from 'rxjs/operators'; import { IMineral } from '../Mineral/IMineral.interface'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class MineralWorldService { constructor(private http: HttpClient) { } getAllMinerals(buySellFilter?: number): Observable<IMineral[]> { // Type the HTTP response directly as IMineral[] return this.http.get<IMineral[]>('data/minerals.json').pipe( map(minerals => { // Apply filter only if a value is provided if (buySellFilter !== undefined) { return minerals.filter(mineral => mineral.BuySell === buySellFilter); } // Return empty array for home/info sections (no minerals shown) return []; }) ); } }
2. Correct Route-Based Filtering in Mineral List Component
Your current component logic for detecting the route is too vague—it will set BuySell=2 for any non-empty route, including the info page. Let's update it to check the actual route path, plus use the async pipe to avoid manual subscription cleanup:
// mineral-list.component.ts import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { MineralWorldService } from 'src/app/services/mineral-world.service'; import { IMineral } from '../IMineral.interface'; import { Observable } from 'rxjs'; @Component({ selector: 'app-mineral-list', templateUrl: './mineral-list.component.html', styleUrls: ['./mineral-list.component.css'] }) export class MineralListComponent implements OnInit { minerals$!: Observable<IMineral[]>; constructor(private route: ActivatedRoute, private mineralworldService: MineralWorldService) { } ngOnInit(): void { const currentRoutePath = this.route.snapshot.routeConfig?.path; let buySellFilter: number | undefined; switch(currentRoutePath) { case 'buy-minerals': buySellFilter = 1; break; case 'sell-minerals': buySellFilter = 2; break; default: // Home or info section: no filter, return empty array buySellFilter = undefined; } this.minerals$ = this.mineralworldService.getAllMinerals(buySellFilter); } }
3. Update the Template for Clean Rendering
Update your mineral-list.component.html to use the async pipe and show appropriate empty states:
<div *ngIf="minerals$ | async as minerals"> <!-- Show minerals only if there are any --> <div class="mineral-grid" *ngIf="minerals.length > 0"> <div class="mineral-card" *ngFor="let mineral of minerals"> <img [src]="`assets/images/${mineral.Image}.jpg`" alt="{{mineral.Name}}" class="mineral-image"> <h3>{{mineral.Name}}</h3> <p><strong>Formula:</strong> {{mineral.Formula}}</p> <p><strong>Price:</strong> ${{mineral.Price}}</p> <p><strong>Quantity:</strong> {{mineral.Quantity}}</p> </div> </div> <!-- Show empty state when no minerals are available --> <div class="empty-state" *ngIf="minerals.length === 0"> No minerals available in this section. </div> </div>
4. Ensure Proper Route Configuration
Make sure your app-routing.module.ts maps the navbar links to the correct components. Assuming you have a home component for the main menu and an info component for the news section:
// app-routing.module.ts import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { MineralListComponent } from './mineral/mineral-list/mineral-list.component'; import { HomeComponent } from './home/home.component'; // Your home component import { MineralInfoComponent } from './mineral-info/mineral-info.component'; // Your info component const routes: Routes = [ { path: '', component: HomeComponent }, // Main menu "Mineral-World" { path: 'buy-minerals', component: MineralListComponent }, { path: 'sell-minerals', component: MineralListComponent }, { path: 'information-about-minerals', component: MineralInfoComponent }, { path: '**', redirectTo: '' } // Catch-all redirect ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
5. Home & Info Section Behavior
Since we set the service to return an empty array when no filter is provided, your home component and info component won't display any buy/sell minerals—exactly what you wanted. If you want to show other content on those pages (like general info about Mineral-World), just build out those components separately without including the app-mineral-list selector.
内容的提问来源于stack exchange,提问作者Mihai Daian

