Angular Resource API实现暂停:停止监听信号但保留最后取值
Angular Resource API 暂停功能实现:保留最后值并停止监听信号变化
需求:实现Angular Resource API的暂停功能,停止监听信号变化但保留最后获取的值。当前调用stop时resource.value()会被清空,需要保留该值用于UI展示,仅停止响应request回调中未来的信号变化。
可复现代码
HTML代码
<div> <div> Resource Request triggers: </div> <div> <input [(ngModel)]="id" type="number"/> </div> </div> <div> @if(![rs.Loading, rs.Reloading].includes(rxResource.status())) { {{rxResource.value() | json}} } @else{ Loading... } </div> <hr/> <div> @if(![rs.Loading, rs.Reloading].includes(resource.status())) { {{resource.value() | json}} } @else{ Loading... } </div> <hr/> <div> <div>Current Status: {{rs[resource.status()]}}</div> <button (click)="start()">Start Listening</button> <button (click)="pause()">Pause Listening (Retain last value)</button> <button (click)="stop()">Stop Listening</button> </div>
TypeScript代码(原始版本)
export class App { id = signal(1); rs = ResourceStatus; http = inject(HttpClient); resourceControl = signal(true); resourceRequest = (): ResourceRequest | undefined => { if (this.resourceControl()) { return { id: this.id(), }; } else { return undefined; } }; resource: ResourceRef<any> = resource<ResourceRequest | undefined, any>({ request: this.resourceRequest, loader: ({ request: { id }, abortSignal }) => { return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, { signal: abortSignal, }).then((res: any) => res.json()); }, }); rxResource: ResourceRef<any> = rxResource<ResourceRequest | undefined, any>({ request: this.resourceRequest, loader: ({ request: { id } }) => { return this.http.get<any>( `https://jsonplaceholder.typicode.com/todos/${id}` ); }, }); start() { this.resourceControl.set(true); } stop() { this.resourceControl.set(false); } pause() { // how to pause the resource and stop listening to future changes but retain the last value } }
解决方案
核心思路:避免通过返回undefined清空资源值,而是通过新增状态控制request回调,暂停时固定返回最后一次有效的请求参数,不再响应id信号的变化。
修改后的TypeScript代码:
export class App { id = signal(1); rs = ResourceStatus; http = inject(HttpClient); resourceControl = signal(true); isPaused = signal(false); lastValidRequest = signal<ResourceRequest | undefined>({ id: 1 }); resourceRequest = (): ResourceRequest | undefined => { // 原stop逻辑:返回undefined清空值 if (!this.resourceControl()) { return undefined; } // 暂停状态:返回最后一次有效请求,不响应id变化 if (this.isPaused()) { return this.lastValidRequest(); } // 正常监听状态:更新最后一次请求并返回当前id const currentRequest = { id: this.id() }; this.lastValidRequest.set(currentRequest); return currentRequest; }; resource: ResourceRef<any> = resource<ResourceRequest | undefined, any>({ request: this.resourceRequest, loader: ({ request: { id }, abortSignal }) => { return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, { signal: abortSignal, }).then((res: any) => res.json()); }, }); rxResource: ResourceRef<any> = rxResource<ResourceRequest | undefined, any>({ request: this.resourceRequest, loader: ({ request: { id } }) => { return this.http.get<any>( `https://jsonplaceholder.typicode.com/todos/${id}` ); }, }); start() { this.resourceControl.set(true); this.isPaused.set(false); } stop() { this.resourceControl.set(false); } pause() { this.isPaused.set(true); } }
方案说明
- 新增
isPaused信号控制暂停状态,lastValidRequest存储最后一次有效的请求参数 - 修改
resourceRequest回调:- 当处于暂停状态时,返回
lastValidRequest的值,不再跟随id信号变化 - 正常监听时,更新
lastValidRequest并返回当前请求参数
- 当处于暂停状态时,返回
start方法重置暂停状态,恢复监听id变化pause方法仅切换暂停状态,不会清空已获取的资源值
内容的提问来源于stack exchange,提问作者Naren Murali
相关产品推荐
相关产品推荐

