angular - 使用角材料自动完成
问题描述
我需要一些关于使用有角材料的自动完成字段的帮助。首先,当页面加载时,我有一项服务对后端节点应用程序进行 API 调用,该应用程序将请求发送到 sanbox api。此调用带来了支持的城市列表。然后它提供给具有表单的城市列表组件。当用户键入我想将城市缩小到自动完成框中时。到目前为止,我已经设置了一个新变量作为主题,并使用 .filter() 和 .include() 方法过滤数组并将其返回给我的主题变量。返回是订阅变量的对象形式,但现在在模板上,我无法使用返回的值来缩小结果范围。我认为它是因为我需要将结果返回到数组中。有人可以帮我概念化这个吗(目前我可以让过滤器缩小结果范围,但数组没有
city-list Component.ts
import { CityService } from "./services/city-list.service";
import { Component, OnInit, OnDestroy } from "@angular/core";
import { City } from "../cities/models/city";
import { Subscription, Observable } from "rxjs";
import { map, startWith, debounceTime } from "rxjs/operators";
import {FormGroup, FormControl, Validators, NgForm} from '@angular/forms';
@Component({
selector: "<app-cities></app-cities>",
templateUrl: "./city-list.component.html"
})
export class CityListComponent implements OnInit, OnDestroy {
cities: City[];
private citiesSub: Subscription;
destinationCity: FormControl = new FormControl();
currentCity: Subscription;
filteredCities: City[];
constructor(public cityService: CityService) {}
ngOnInit() {
this.cityService.getCities();
this.citiesSub = this.cityService
.getCityUpdateListener()
.subscribe((cities) => {
this.cities = cities;
});
this.currentCity = this.destinationCity.valueChanges.pipe(
debounceTime(400),
startWith(''),
).subscribe(term=>{
if(!term){
return;
}
this._filter(term);
}
);
}
private _filter(value: string): City[] {
const filterValue = value.toLowerCase();
return this.filteredCities = this.cities.filter(option => option.name.toLocaleLowerCase().includes(filterValue));
}
ngOnDestroy() {
this.citiesSub.unsubscribe();
}
onSearch(form: NgForm){
console.log(form.value);
}
}
city service.ts
import { Subject } from 'rxjs';
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { map } from "rxjs/operators";
import {City} from '../models/city';
@Injectable({ providedIn: "root" })
export class CityService {
cities: City[] = [];
private updatedCities = new Subject<City[]>();
constructor(private http: HttpClient) {}
getCities() {
this.http.get<{message: string; cities: City[]}>('http://localhost:3000/cities')
.pipe(
map((cityData)=>{
return cityData.cities.map(city=>{
return{
code: city.code,
name: city.name
};
});
})
)
.subscribe((transCity) => {
this.cities = transCity;
// console.log(this.cities);
this.updatedCities.next([...this.cities]);
});
}
getCityUpdateListener() {
return this.updatedCities.asObservable();
}
}
city-list.html
<mat-card>
<form #instantFlight="ngForm">
<mat-form-field>
<input type="text" id="destinationCity" name="destinationCity" matInput [formControl]="destinationCity" [matAutocomplete]="autoDestination">
<mat-autocomplete #autoDestination="matAutocomplete">
<mat-option *ngFor="let c of cities" [value]="c.code">
{{c.name}} - {{c.code}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<button mat-raised-button type="submit">Search</button>
</form>
</mat-card>
解决方案
import { CityService } from "./services/city-list.service";
import { Component, OnInit, OnDestroy } from "@angular/core";
import { City } from "../cities/models/city";
import { Subscription, Observable } from "rxjs";
import { map, startWith, debounceTime } from "rxjs/operators";
import { FormGroup, FormControl, Validators, NgForm } from "@angular/forms";
@Component({
selector: "<app-cities></app-cities>",
templateUrl: "./city-list.component.html",
styleUrls: ["./cities-list.component.css"]
})
export class CityListComponent implements OnInit, OnDestroy {
cities: City[]=[];
private citiesSub: Subscription;
currentCity: Observable<City[]>;
destinationCity: FormControl = new FormControl();
originCity: FormControl = new FormControl();
startDate: FormControl = new FormControl();
constructor(public cityService: CityService) {}
ngOnInit() {
this.cityService.getCities();
this.citiesSub = this.cityService
.getCityUpdateListener()
.subscribe(cities => {
this.cities = cities;
});
this.currentCity = this.destinationCity.valueChanges
.pipe(
startWith(''),
debounceTime(10),
map(x=>{
return this._filter(x);
}
));
}
private _filter(value: string): City[]{
const filterValue = value.toLowerCase();
return(this.cities.filter(option => option.name.toLowerCase().includes(filterValue)));
}
ngOnDestroy() {
this.citiesSub.unsubscribe();
}
}
<mat-card>
<form (submit)="onLogin(instantFlight)" #instantFlight="ngForm">
<mat-form-field>
<input type="text" id="destinationCity" name="destinationCity" matInput [formControl]="destinationCity" [matAutocomplete]="autoDestination">
<mat-autocomplete #autoDestination="matAutocomplete">
<mat-option *ngFor="let c of currentCity | async" [value]="c.code">
{{c.name}} - {{c.code}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-form-field>
<input type="text" id="originCity" name="originCity" matInput [formControl]="originCity" [matAutocomplete]="autoOrigin">
<mat-autocomplete #autoOrigin="matAutocomplete">
<mat-option *ngFor="let c of cities" [value]="c.code">
{{c.name}} - {{c.code}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<mat-form-field>
<input matInput id="startDate" name="startDate" [formControl]="startDate" [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<button mat-raised-button type="submit" color="accent">Search</button>
</form>
</mat-card>
推荐阅读
- python - 应该如何使用 Pool 初始值设定项参数
- reactjs - 使用状态更改导入的 SVG 组件颜色
- scala - 为 Play Framework Api 创建服务代理
- android - HERE Android SDK(高级版)错误:MISSING_LIBRARIES:缺少本机库:MAPSJNI
- swift - URLSession dataTaskPublisher 重试为 MJPEG 流
- json - 如何从 Flux 获取 JSON 格式
在 SpringBoot 控制器中? - javascript - 是否可以使此删除按钮和输入表单起作用?
- reactjs - 如何根据键过滤地图返回的数据
- c# - 从种子字符串计算特定长度的哈希字符串
- python - Return the index from ordinal position pandas dataframe