angular - 如何在 REST-API 端点使用 Observables 进行分页?
问题描述
我正在使用 Angular 7 并构建一个从 REST-API 端点检索数据的 web 应用程序。用户将他们的搜索字符串放入formControl
可观察的公共字段中。如果输入字段中的值发生变化,则会向 API 端点发送一个 http 请求。最后,我将 http 响应作为我可以订阅的 observable 获得。但是查询结果也可以有100多个项目。然后 API 端点将 NEXT 链接发送到第二页,依此类推(API 端点分页)。
我现在的问题是,我找不到正确的方法来观察搜索输入字段并遍历从 API 端点获得的所有 NEXT 页面。分开它就像一个魅力。
有人对我的用例有好的做法吗?
我的组件文件:
export class GeomapComponent implements OnInit {
searchTerm = new FormControl();
constructor(private geomapService: GeomapService) { }
ngOnInit() {
this.searchTerm.valueChanges.pipe(
debounceTime(400),
distinctUntilChanged(),
switchMap(term => this.geomapService.retrieveApi(term))
).subscribe(data => {
if (data['results']) {
......
}
}
}
}
我的服务文件:
export class GeomapService {
retrieveUrl = new Subject<string>();
constructor(private http: HttpClient) { }
public retrieveApi(searchTerm: string): Observable<ApiDataResponse> {
this.retrieveUrl.next(baseApiUrl + '?q=' + searchTerm);
return this.retrieveUrl.pipe(
switchMap(url => this.sendRequest(url)),
).subscribe(data => {
if (data['next']) {
this.retrieveUrl.next(data['next']);
}
});
}
public sendRequest(url: string, httpOptions = {}): Observable<ApiDataResponse> {
return this.http.get<ApiDataResponse>(url);
}
}
不幸的是,我收到以下错误:
TS2322:“订阅”类型不可分配给“可观察”类型。“订阅”类型中缺少属性“_isScalar”。
更新: 现在我走得更远了,因为我意识到我必须在服务中合并/合并顺序传入的 observables(由循环提供)。
public requestApi(requestUrl: string): Observable<ApiDataResponse> {
return this.sendRequest(requestUrl).pipe(
mergeMap(result => {
if (result['next']) {
return this.requestApi(result['next']);
} else {
return of(result);
}
})
);
}
尽管如此,我仍然坚持使用正确的组合/转换运算符,因为在这个阶段mergeMap
我订阅了最后一个响应的结果。但我也希望获得之前收到的所有回复并将其合并为一个值。
有人知道运算符中的返回应该是什么样子吗?
更新:
代码更新,删除了数组问题(ApiDataResponse[]
--> ApiDataResponse
)
解决方案
所以,如果我理解得很好,你在搜索字段上有一个 observable,当你搜索时,你会调用 API 来获取结果。如果结果 > 100,那么您的 API 会发送前 100 个结果并告诉您对接下来的 100 个结果进行另一个请求,直到没有更多结果为止。
对我来说,您需要一次获得所有结果有点奇怪,不是发送 100 个第一个结果以等待用户请求 100 个下一个结果(例如,通过单击“下一页按钮“或滚动到某个限制)?
我将通过将最初的前 100 个结果存储在显示它们的组件中(可能在 BehaviourSubject 中)以及何时获取结果的下一部分(例如,当滚动位置达到一定数量或当用户单击下一个按钮),然后如果有任何结果,我会请求下一个结果...
推荐阅读
- sql - 如果在 Hive SQL 中找不到匹配项,则提供要加入的备用列
- c# - ASP 核心 API 2.2。RequireClaim 和 RequireAuthenticatedUser 策略不起作用
- ruby - Rails request.referer 没有重定向到上一个 url
- re2 - 如何匹配任何不包含 Re2 中特定单词的字符串
- jquery - 确定是按月付款还是按年付款
- powershell - 如何通过 Caml 克服 SharePoint Online 5000 行限制?
- angular - 以角度运行异步代码的语法
- javascript - 如何创建创建新网格项 onClick 的函数?Vuex 使用 vue-grid-layout
- javascript - Rxjs 可以将其更改为返回布尔值吗?
- python - 如果索引位置值在变量中定义,可以通过索引位置访问 Jinja 模板变量吗?