Angular 4表单:基于表单输入展示航班搜索结果技术求助
Hey there! Let's get that flight search filtering up and running. You've already nailed the API data fetching and basic form structure—nice work! Here's how to connect the dots between user input and filtered results:
Step 1: Set Up Two-Way Data Binding for the Form
First, we need to capture user inputs from the form. Angular's [(ngModel)] makes this easy, but you'll need to import FormsModule in your app module first (don't forget this step!).
Update your HTML form elements to include name attributes and two-way binding:
<!-- Search Form --> <form class="" (ngSubmit)="onSearch()" method="post"> <h1> Let's Go. </h1> <hr> <select [(ngModel)]="searchCriteria.travelMode" name="travelMode"> <option value="">Select means of Travel</option> <option value="flight">Flight</option> </select> <label for="startDate">Travel Start Date</label> <input type="date" [(ngModel)]="searchCriteria.startDate" name="startDate" id="startDate"> <label for="endDate">Travel End Date</label> <input type="date" [(ngModel)]="searchCriteria.endDate" name="endDate" id="endDate"> <select [(ngModel)]="searchCriteria.departureCity" name="departureCity"> <option value="">Departure Location</option> <option value="Atlanta">Atlanta</option> </select> <select [(ngModel)]="searchCriteria.arrivalCity" name="arrivalCity"> <option value="">Arrival Location</option> <option value="San Francisco">San Francisco</option> </select> <select [(ngModel)]="searchCriteria.cabinClass" name="cabinClass"> <option value="">Product Class</option> <option value="economy">Economy</option> </select> <input style="width: 100px; background-color: green; color: #eef; height: 40px; border-radius: 50px; margin: 0 auto; margin-top: 50px;" type="submit" value="Submit"> </form> <!-- Results --> <div class="result"> <ul> <li *ngFor="let group of displayItems"> <div class="flight-card"> <div class="availability"> <h5> Availability: {{group.availability}} </h5> </div> <div class="price"> {{ group.price.symbol }} {{ group.price.amount }} <p>{{ group.price.currency }}</p> </div> <div class="arrival"> <h5> Arrival City: </h5>{{group.arrival.city}}<br> <h5> Arrival Airport Name: </h5>{{group.arrival.airport.name}}<br> <h5> Arrival Time: </h5>{{group.arrival.time}}<br><br> </div> <hr> <div class="departure"> <h5> Departure City: </h5>{{group.departure.city}}<br> <h5> Departure Airport Name: </h5>{{group.departure.airport.name}}<br> <h5> Departure Time: </h5>{{group.departure.time}}<br><br> </div> </div> </li> </ul> </div>
(Note: I fixed a typo from "depature" to "departure" in your results section—small detail, but good to have!)
Step 2: Update the Component with Filter Logic
Now, let's add the necessary code to your component to handle the form submission and filtering:
import { Component } from '@angular/core'; import { Http, Response } from '@angular/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { result: any; errorFromSubscribe: any; errorFromCatch: any; displayItems: any[]; allFlights: any[]; // Store all fetched flights here for repeated filtering searchCriteria: any = {}; // Holds all user's search inputs constructor(private http: Http) {} ngOnInit(): void { // Fetch all flights on component load this.http.get('https://api.myjson.com/bins/1gb9tf') .subscribe( (res: Response) => { this.result = res.json(); this.allFlights = this.result['results']; this.displayItems = this.allFlights; // Show all flights initially console.log(this.result); }, error => { console.log(error); this.errorFromSubscribe = error; } ); } onSearch(): void { // Filter flights based on the user's search criteria this.displayItems = this.allFlights.filter(flight => { // Check departure city (skip if user didn't select one) const matchesDeparture = !this.searchCriteria.departureCity || flight.departure.city === this.searchCriteria.departureCity; // Check arrival city (skip if user didn't select one) const matchesArrival = !this.searchCriteria.arrivalCity || flight.arrival.city === this.searchCriteria.arrivalCity; // Check cabin class (adjust the key if your API uses a different property name) const matchesClass = !this.searchCriteria.cabinClass || flight.class?.toLowerCase() === this.searchCriteria.cabinClass.toLowerCase(); // Check start date (assuming flight departure time starts with YYYY-MM-DD; adjust if your format differs) const matchesStartDate = !this.searchCriteria.startDate || flight.departure.time.startsWith(this.searchCriteria.startDate); // Check end date (adjust logic based on how your return flight data is structured) const matchesEndDate = !this.searchCriteria.endDate || flight.arrival.time.startsWith(this.searchCriteria.endDate); // Only keep flights that match all applicable conditions return matchesDeparture && matchesArrival && matchesClass && matchesStartDate && matchesEndDate; }); } title = 'app'; }
Step 3: Don't Forget to Import FormsModule!
In your app.module.ts, add FormsModule to the imports array so Angular recognizes [(ngModel)]:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; // Import this import { HttpModule } from '@angular/http'; // Ensure HttpModule is included too import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, FormsModule, HttpModule], // Add FormsModule here providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Quick Notes:
- We store all fetched flights in
allFlightsso we can re-filter from the full dataset every time the user searches (instead of filtering already filtered results). - The
filtermethod skips any condition if the user didn't fill that field—so if they only select a departure city, it filters just by that. - Adjust the date matching logic if your API's time format uses timestamps or a different string structure.
- For cabin class, I assumed your flight data has a
classproperty—modify that to match your actual API response if needed.
That should get your search filtering working perfectly! Let me know if you run into any snags with your specific API data structure.
内容的提问来源于stack exchange,提问作者Eddie Taliaferro II

