如何在NgRx SignalStore中等待RxMethod的返回结果?
解决异步调用后获取Signal值的问题
你的核心问题在于getBankWidget()是异步操作,但你在调用后立即同步访问isWidgetLink$$(),此时异步请求还未完成,widgetBankLinks还没更新,导致链接为空。可以通过以下几种方式解决:
方案1:让getBankWidget()返回Observable,主动等待完成
首先修改UserApplication,让getBankWidget()返回异步操作的Observable,这样组件可以明确知道操作何时完成:
export class UserApplication { private readonly store = inject(CustomerStore); // 修改方法,返回rxMethod的Observable getBankWidget(): Observable<void> { return this.store.getBankWidget(); } // 其余getter保持不变 get isLinxoId(): Signal<boolean | null> { return this.store.isLinxoId; } get isWidget(): Signal<boolean | null> { return this.store.isWidget; } get customer(): Signal<Customer | null> { return this.store.customer; } get widgetBankLinks(): Signal<WidgetBankLinks | undefined> { return this.store.widgetBankLinks; } }
然后在组件的addBank()方法中,通过订阅或async/await等待操作完成后再处理链接:
方式A:使用async/await
async addBank() { try { // 等待异步操作完成 await this._customerApp.getBankWidget().toPromise(); // 此时widgetBankLinks已更新,安全获取链接 const connectionLink = this.isWidgetLink$$()?._links?.add_connection; if (connectionLink) { this.sanitizedWidgetLink = this._sanitizer.bypassSecurityTrustResourceUrl(connectionLink); this.showIframe = true; } } catch (error) { console.error('获取银行Widget失败:', error); // 这里可以添加错误提示逻辑 } }
方式B:使用Observable订阅
addBank() { this._customerApp.getBankWidget().subscribe({ next: () => { const connectionLink = this.isWidgetLink$$()?._links?.add_connection; if (connectionLink) { this.sanitizedWidgetLink = this._sanitizer.bypassSecurityTrustResourceUrl(connectionLink); this.showIframe = true; } }, error: (err) => { console.error('获取银行Widget失败:', err); // 错误处理逻辑 } }); }
方案2:使用Effect响应式监听Signal变化
更符合Angular Signal响应式风格的做法是,用effect监听widgetBankLinks的变化,当它有有效值时自动处理链接:
export class AssetsComponent implements OnInit { private readonly _customerApp = inject(UserApplication); private readonly _sanitizer = inject(DomSanitizer); private readonly _effect = inject(EffectRef); isLinxoId$$ = this._customerApp.isLinxoId; isWidgetLink$$ = this._customerApp.widgetBankLinks; isWidget$$ = this._customerApp.isWidget; // 优化类型,避免any sanitizedWidgetLink: SafeResourceUrl | null = null; showIframe: boolean = false; ngOnInit(): void { if (!this.isLinxoId$$()) this._customerApp.createBankUser(); // 监听widgetBankLinks的变化,自动处理链接 this._effect(() => { const widgetLinks = this.isWidgetLink$$(); const connectionLink = widgetLinks?._links?.add_connection; if (connectionLink) { this.sanitizedWidgetLink = this._sanitizer.bypassSecurityTrustResourceUrl(connectionLink); this.showIframe = true; } else { this.sanitizedWidgetLink = null; this.showIframe = false; } }); } addBank() { // 只需触发异步请求,剩下的交给effect自动处理 this._customerApp.getBankWidget(); } }
这种方式不需要手动管理异步流程,只要widgetBankLinks更新,effect就会自动执行,更简洁且符合Signal的设计理念。
内容的提问来源于stack exchange,提问作者Zed
相关产品推荐
相关产品推荐

