Angular遍历对象编译报错 适配Angular+RxJS动态搜索示例如何修复
错误修复方案
错误核心原因
async管道仅支持接收Observable/Promise类型的异步对象,你当前代码中声明的results$是普通数组类型,不符合async管道的入参要求,因此触发类型不匹配的编译错误。- 除此之外代码还存在3处逻辑问题:
- 命名带
$后缀的变量按RxJS约定应为Observable类型,你将它初始化为普通数组不符合类型定义 ngModelChange事件抛出的$event是输入框的当前文本值,不是KeyboardEvent类型,searchSubject$的类型定义错误,distinctUntilChanged无法正确对比搜索内容queryAPI已经通过map返回了结果数组,subscribe中再取x.results属于取值逻辑错误,会导致运行时无数据
- 命名带
推荐修复方案(保留RxJS+async管道写法,符合Angular最佳实践)
修正后的TS代码
import { Component } from '@angular/core'; import { Observable } from 'rxjs'; import { map, switchMap, Subject, debounceTime, distinctUntilChanged } from 'rxjs'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { constructor(private http: HttpClient){} searchString = ''; // 定义为Observable类型,符合$后缀命名约定 results$!: Observable<any[]>; // Subject泛型改为字符串类型,对应搜索内容 searchSubject$ = new Subject<string>(); ngOnInit() { // 直接将pipe后的Observable赋值给results$,无需手动subscribe管理订阅 this.results$ = this.searchSubject$.pipe( distinctUntilChanged(), debounceTime(200), switchMap((searchString: string) => this.queryAPI(searchString)) ); } queryAPI(searchString: string) { return this.http.get(`https://www.reddit.com/r/aww/search.json?q=${searchString}`).pipe( map((result:any) => result['data']['children']) ); } inputChanged(value: string) { console.log('input changed', value); this.searchSubject$.next(value); } }
HTML代码无需修改,保留async管道即可。
备选修复方案(不用async管道,用普通数组接收结果)
如果不想用Observable+async的写法,你可以直接去掉HTML中的async管道,修改如下:
- HTML中把
*ngFor="let result of results$ | async"改为*ngFor="let result of results" - TS中修改对应变量和逻辑:
// 删掉$后缀,明确定义为普通数组 results: any[] = []; // ngOnInit中保留subscribe,修正取值逻辑 ngOnInit() { this.searchSubject$.pipe( distinctUntilChanged(), debounceTime(200), switchMap((searchString: string) => this.queryAPI(searchString)) ).subscribe(data => { // 直接赋值数组,不需要取results属性 this.results = data; }); }
内容的提问来源于stack exchange,提问作者SimonD
相关产品推荐
相关产品推荐

