Angular 在第一次点击焦点时开始

Angular 在第一次点击焦点时开始,angular,rxjs6,angular-material-5,Angular,Rxjs6,Angular Material 5,使用AutoComplete从API中提取城市,然后允许用户搜索出行。 问题是,即使我使用的是startWith,我首先必须在字段中单击,然后开始键入以使其工作,但当用户关注该输入框时,我无法立即显示下拉列表。 作为解决方案,我想在填充cities变量的订阅之后调用它。我该怎么做?该列表是否应作为可观察的?然后继续并重新订阅 从“/services/city list.service”导入{CityService}; 从“@angular/core”导入{Component,OnInit,On

使用AutoComplete从API中提取城市,然后允许用户搜索出行。 问题是,即使我使用的是startWith,我首先必须在字段中单击,然后开始键入以使其工作,但当用户关注该输入框时,我无法立即显示下拉列表。 作为解决方案,我想在填充cities变量的订阅之后调用它。我该怎么做?该列表是否应作为可观察的?然后继续并重新订阅

从“/services/city list.service”导入{CityService};
从“@angular/core”导入{Component,OnInit,OnDestroy};
从“./cities/models/City”导入{City};
从“rxjs”导入{Subscription,Observable};
从“rxjs/operators”导入{map,startWith,debounceTime};
从“@angular/forms”导入{FormGroup,FormControl,Validators,NgForm};
@组成部分({
选择器:“”,
templateUrl:“./city list.component.html”,
样式URL:[“/”城市列表.component.css“]
})
导出类CityListComponent实现OnInit、OnDestroy{
城市:城市[]=[];
私人花旗集团:认购;
当前城市:可观察;
destinationCity:FormControl=新FormControl();
原始性:FormControl=新FormControl();
startDate:FormControl=新FormControl();
构造函数(公共城市服务:城市服务){}
恩戈尼尼特(){
this.cityService.getCities();
this.citiesSub=this.cityService
.getCityUpdateListener()
.订阅(城市=>{
这个。城市=城市;
});
this.currentCity=this.destinationCity.valueChanges
.烟斗(
去BounceTime(100),
startWith(“”),
地图(x=>{
返回此过滤器(x);
}
));
}
私有过滤器(值:字符串):城市[]{
常量filterValue=value.toLowerCase();
返回(this.cities.filter(option=>option.name.toLowerCase().includes(filterValue));
}
恩贡德斯特罗(){
this.citiesSub.unsubscribe();
}
}

{{c.name}}-{c.code}
{{c.name}}-{c.code}
搜寻

在这种情况下,
startWith
实际上会发出空字符串值和地图函数,但在分配
之前,第一次发射已经完成。下一次发射实际上是当
值更改时
再次发射

因此,我们可以在第一个可观测城市发射时运行
map
方法。实际上,我们只想在任何一个可见光发射时运行
map
方法。我们可以通过一点重构和使用最新版本来实现这一点:

  ngOnInit() {
    this.cityService.getCities();
    this.cities = this.cityService.getCityUpdateListener();

    this.currentCity = this.destinationCity.valueChanges
    .pipe(
      debounceTime(100),
      withLatestFrom(this.cities)
      map([value, cities] => cities.filter(s => s.name.toLowerCase().includes(value.toLowerCase)));
    ));

  }
withLatestFrom
将等待给定的可观察对象发出至少一个值,然后继续流。因为这里的观察速度较慢,所以
map
函数只有在发出某种信息后才会运行。它还从两个观测值中发出一个成对的值,所以一些解构处理了这个问题

我们还可以更改您的
\u filter
函数,以接受
cities
参数,或者只进行内联筛选,因为我们不再有
this.cities
静态数组值。我喜欢第二种方法,因为它将所有与流相关的数据保存在一个流中

此外,在
cities
上重复此更改时,需要在标记中使用异步管道。不过这很好,因为
async
管道自动处理取消订阅。

从“./services/city list.service”导入{CityService};
从“@angular/core”导入{Component,OnInit,OnDestroy};
从“./models/City”导入{City};
从“rxjs”导入{Subscription,Observable};
从“rxjs/operators”导入{map,filter,startWith,withLatestFrom,debounceTime};
从“@angular/forms”导入{FormGroup,FormControl,Validators,NgForm};
@组成部分({
选择器:'应用程序城市列表',
templateUrl:'./city list.component.html',
样式URL:['./城市列表.component.css']
})
导出类CityListComponent实现OnInit{
城市:可见;
私人花旗集团:认购;
当前城市:可观察;
试验城市:可观察;
destinationCity:FormControl=新FormControl();
原始性:FormControl=新FormControl();
startDate:FormControl=新FormControl();
构造函数(公共城市服务:城市服务){}
恩戈尼尼特(){
this.cityService.getCities();
this.cities=this.cityService.getCityUpdateListener();
this.currentCity=this.destinationCity.valueChanges
.烟斗(
最近从(这个城市)开始,
去BounceTime(100),
地图(
([第一,第二]=>{
返回此过滤器(第一个,第二个);
}
)
);
}
私人_过滤器(第一、第二):城市[]{
常量filterValue=first.toLowerCase();
返回(second.filter(option=>option.name.toLowerCase().includes(filterValue));
}
}

{{c.name}}-{c.code}
{{c.name}}-{c.code}
搜寻

我已经尝试过这个方法,它看起来很有效,但是现在我没有我的cities数组,而是使用了一个testCities可观察对象,我不能使用。filter我必须使用rxjs。对一个可观察对象进行筛选,但我得到了一个errorWell,
withLatestFrom
还将输出第二个可观察对象的值,所以我们可以将它合并到同一个流中。我会更新我的答案。对,但我不能用cities来做,因为它是City[]类型的变量,而updateListener()是observable类型的变量。相反,我使用了另一个observable,但无法使用.filter方法。只需更新
城市
,键入
observable
,然后查看更新后的代码即可!只需要用正确的语法发布一个更新的答案