如何让3个<select>元素联动实现过滤功能(JHipster+Angular)
Hey there! Let's tackle this select filter联动 problem step by step for your JHipster 4.14.0 + Angular project. Since you've already set up the frontend services, we'll focus on modifying the backend REST endpoints and tying everything together on the frontend.
Step 1: Add Filtered Endpoints to Backend Resources
First, we need to create new REST endpoints in HotspotResource.java and ProcessResource.java that return items filtered by the selected operation ID.
For HotspotResource.java:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; // ... existing imports and class definition @GetMapping("/by-operation/{operationId}") @Timed public List<Hotspot> getHotspotsByOperation(@PathVariable Long operationId) { log.debug("REST request to fetch Hotspots linked to Operation ID: {}", operationId); // Use your repository method to filter hotspots by operation ID // If you don't have this method yet, add it to HotspotRepository: // List<Hotspot> findByOperationId(Long operationId); return hotspotRepository.findByOperationId(operationId); }
For ProcessResource.java:
// ... existing imports and class definition @GetMapping("/by-operation/{operationId}") @Timed public List<Process> getProcessesByOperation(@PathVariable Long operationId) { log.debug("REST request to fetch Processes linked to Operation ID: {}", operationId); // Add this method to ProcessRepository if missing: // List<Process> findByOperationId(Long operationId); return processRepository.findByOperationId(operationId); }
Step 2: Update Frontend Services to Call New Endpoints
Next, extend your HotspotService and ProcessService to include methods that call these filtered endpoints.
In hotspot.service.ts:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Hotspot } from 'app/shared/model/hotspot.model'; @Injectable({ providedIn: 'root' }) export class HotspotService { private resourceUrl = 'api/hotspots'; constructor(private http: HttpClient) {} // ... existing methods getHotspotsByOperation(operationId: number): Observable<Hotspot[]> { return this.http.get<Hotspot[]>(`${this.resourceUrl}/by-operation/${operationId}`); } }
In process.service.ts:
// ... existing imports and class definition export class ProcessService { private resourceUrl = 'api/processes'; constructor(private http: HttpClient) {} // ... existing methods getProcessesByOperation(operationId: number): Observable<Process[]> { return this.http.get<Process[]>(`${this.resourceUrl}/by-operation/${operationId}`); } }
Step 3: Handle Filter Logic in the Component
Update your event-angjs.component.ts to listen for changes in the operation select, then fetch the filtered processes and hotspots.
import { Component, OnInit } from '@angular/core'; import { ProcessService } from 'app/entities/process/process.service'; import { HotspotService } from 'app/entities/hotspot/hotspot.service'; import { Process } from 'app/shared/model/process.model'; import { Hotspot } from 'app/shared/model/hotspot.model'; @Component({ selector: 'jhi-event-angjs', templateUrl: './event-angjs.component.html' }) export class EventAngjsComponent implements OnInit { selectedOperationId: number | null = null; filteredProcesses: Process[] = []; filteredHotspots: Hotspot[] = []; operations: any[] = []; // Assume you already load all operations here constructor( private processService: ProcessService, private hotspotService: HotspotService ) {} ngOnInit(): void { // Load your initial operations list here if not already done } onOperationSelected(): void { if (this.selectedOperationId) { // Fetch filtered processes this.processService.getProcessesByOperation(this.selectedOperationId).subscribe({ next: (data) => { this.filteredProcesses = data; // Optional: Clear selected process/hotspot when operation changes this.selectedProcessId = null; }, error: (err) => console.error('Failed to load processes:', err) }); // Fetch filtered hotspots this.hotspotService.getHotspotsByOperation(this.selectedOperationId).subscribe({ next: (data) => { this.filteredHotspots = data; this.selectedHotspotId = null; }, error: (err) => console.error('Failed to load hotspots:', err) }); } else { // Reset filters if no operation is selected this.filteredProcesses = []; this.filteredHotspots = []; this.selectedProcessId = null; this.selectedHotspotId = null; } } }
Step 4: Bind Everything in the HTML Template
Update your event-angjs.component.html to link the select elements to the component logic:
<!-- Operation Filter --> <select [(ngModel)]="selectedOperationId" (change)="onOperationSelected()"> <option value="">-- Select Operation --</option> <option *ngFor="let op of operations" [value]="op.id">{{op.name}}</option> </select> <!-- Process Filter (disabled until operation is selected) --> <select [(ngModel)]="selectedProcessId" [disabled]="!selectedOperationId"> <option value="">-- Select Process --</option> <option *ngFor="let process of filteredProcesses" [value]="process.id">{{process.name}}</option> </select> <!-- Hotspot Filter (disabled until operation is selected) --> <select [(ngModel)]="selectedHotspotId" [disabled]="!selectedOperationId"> <option value="">-- Select Hotspot --</option> <option *ngFor="let hotspot of filteredHotspots" [value]="hotspot.id">{{hotspot.name}}</option> </select>
Quick Notes
- Make sure your
HotspotandProcessentities have a relationship to theOperationentity (with anoperationIdfield) so the repository queries work. - Add error handling as needed (like showing toast notifications instead of just console logs) for better user experience.
- If you need additional filtering (e.g., hotspots filtered by both operation and process), you can extend the backend endpoints to accept multiple parameters.
内容的提问来源于stack exchange,提问作者G_M12

