在“搜索”服务方法中,我将返回名称中包含搜索关键字的项目:
// data.service.ts
import { Injectable } from '@angular/core';
import { Observable, pipe, of } from 'rxjs';
import { map, filter, flatMap } from 'rxjs/operators';
import { Goodie } from './models/Goodie';
@Injectable({
providedIn: 'root'
})
export class DataService {
public goodies = [
{ name: 'Brownie Pillow Cookie'},
{ name: 'Talenti Pistachio' },
{ name: 'SnickerDoodle' }
];
constructor() {}
public getGoodies(): Observable<Goodie[]> {
return of(this.goodies);
}
public search(keyword): Observable<Goodie> {
return this.getGoodies().pipe(
flatMap(data => data),
filter(g => g.name.toLowerCase().includes(keyword.toLowerCase()))
);
}
}
当名称上存在关键字匹配时,这有效(返回项目)。例如,搜索“e”会返回结果,我可以在控制台中看到这些结果:
// app.component.ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { DataService } from './data.service';
import { Goodie } from './models/Goodie';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
public searchResult: Goodie[] = [];
constructor(private storeService: DataService) {}
handleSearch(type, keyword) {
this.searchResult = [];
this.storeService.search(keyword).subscribe(data => {
console.log('-----------');
this.searchResult.push(data);
console.log(this.searchResult);
console.log('-----------');
});
}
}
但是如果我搜索与任何项不匹配的关键字,例如“x”,那么不仅没有返回结果,而且没有任何内容从this.storeService.search(keyword)内部记录到控制台。 subscribe方法 - 控制台甚至不打印语句console.log('-----------')。
因此,我希望澄清两件事:
以下是StackBlitz的示例: https://stackblitz.com/edit/cookies-bakery
答案 0 :(得分:1)
正如@ user184994所说,使用普通的旧array.filter来获得结果。
正如你猜测的那样,当搜索没有匹配时,一个可观察的单个项目(与数组的可观察对象)不会发出任何东西。
这修复了您的示例代码
public search(keyword): Observable<Goodie[]> {
// return this.getGoodies().pipe(
// flatMap(data => data),
// filter(g => g.name.toLowerCase().includes(keyword.toLowerCase()))
// );
return of(
this.goodies.filter(g =>
g.name.toLowerCase().includes(keyword.toLowerCase())
)
);
}
但是如果你的组件中绝对需要一个单独的项目流,你可以在没有找到任何内容时从搜索中发出错误,并在订阅中捕获它。
public search(keyword): Observable<Goodie> {
const results = this.goodies.filter(g =>
g.name.toLowerCase().includes(keyword.toLowerCase())
);
return results.length ? from(results) : throwError("Not found");
}
handleSearch(keyword) {
this.searchResult = [];
this.storeService.search(keyword).subscribe(
data => {
console.log('-----------');
this.searchResult.push(data);
console.log(this.searchResult);
console.log('-----------');
},
err => this.err = err
);
}
以下是经过修改的StackBlitz
或者,如果您不喜欢将错误处理用作逻辑的一部分,那么您的服务可以发出结果计数的可观察值,可以在组件中单独订阅。