JavaScript的Reactive Extensions(RxJS)是一组库,用于使用可观察集合和Array Extras样式组合来编写异步和基于事件的程序。
我正在 Angular 应用程序中实现功能,其中对同一数据的多个并发提取应该会产生一个 HTTP 请求,并且该请求在所有并发之间共享
我有一个 Angular 应用程序,需要多次调用 Spring Boot API。首先,调用返回条目对象列表。每个 Entry 对象都有一个名为 medIds 的属性,它是一个 List ...
我正在尝试使用基于回调的node.js库,使用rxjs,看看是否可以以简单的方式做到这一点。 有人可以使用 rxjs 编写这段代码吗?我的意思是删除回调并...
我需要使用 rxjs 运算符找到解决方案。我正在使用 ngrx 开发一个角度应用程序,我想等待 ngrx 选择器被填充。 我有一个通知效果,我打电话给 sse Ser...
我有一个组件需要多个 get 请求才能返回我需要的所有数据。这些是彼此独立的,但我想将所有调用放在一起并在此之后加载 UI ...
在列表上的指令中使用 junctionObservable 来隐藏按钮
我正在尝试编写一些代码,允许我观察可滚动列表,我想检查列表的第一项是否可见,如果是,则不要使按钮可见,但如果第一个
我从反应式编程开始,我有以下应用程序: 三个点是一个 标签。每次单击 li 项目时,应用程序都会使用路由导航到路线... 我从反应式编程开始,我有以下应用程序: 三个点的项目是一个 <ul> 标签。每次单击 li 项目时,应用程序都会使用附加查询字符串的 routerLink 导航到路线(/bands、/bands?active=false 和 /bands?active=true)。 网页中从 Bands 开始的部分(属于称为 band-list 的组件)是 router-outlet 根据路由显示的内容。下面的网格是根据查询参数“active”加载的。然后,每次单击 li 项目时,网格都会重新加载。 此外,刷新数据按钮会重新加载网格。 我正在尝试使用反应式编程来实现以下逻辑: 初始化时,band-list组件应根据路线中的active查询参数加载网格。 每次用户单击 li 时,网格都应该重新加载。如果在此之前单击 li 网格仍在加载(发出 http 请求),则应取消正在进行的 http 请求(在我看来,这就像一个 switchMap 运算符)。 如果用户单击 refresh data button 并且网格已完成加载其数据,则网格应该加载。但是,如果网格仍在加载其数据(在 http 请求中间),则单击不应执行任何操作,即,进程内加载数据操作应完成,并且按钮中的单击实际上会被忽略(这看起来就像我的 exhaustMap :S) 另外,每次执行http操作时,当http操作未完成时,应该出现一条消息告诉“正在加载...”,并且网格中的数据应该被清空。当 http 请求完成时,“正在加载...”消息应该被删除,并且数据应该显示在网格中。 我在 band-list 组件中实现了代码,就像下一个代码块一样,但我不确定在我的解决方案中使用 defer 运算符。我使用了 defer 运算符,因为如果当前请求正在处理中,我需要使用 defer 运算符内的 isLoading 变量来维护状态,并且还要更新此变量作为 tap 运算符中的副作用操作,并使用此变量作为 filter 运算符中的副作用。 我的问题是:根据反应式编程,这是一种很好的方法吗?我还能做什么更好? 您可以在 this stackblitz' url 中检查此解决方案 @Component({ selector: 'app-band-list', templateUrl: 'band-list.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) export class BandListComponent { readonly initialState: BandState = { data: [], isLoading: false }; #bandDataService = inject(BandDataService); refreshDataClickSubject = new Subject<void>(); #activedRoute = inject(ActivatedRoute); bandState$; constructor() { this.bandState$ = this.getBands$(); const destroyRef = inject(DestroyRef); destroyRef.onDestroy(() => { this.refreshDataClickSubject.complete(); this.refreshDataClickSubject.unsubscribe(); }); } getBands$(): Observable<BandState> { const queryParams$ = this.#activedRoute.queryParams; const refreshDataClick$ = this.refreshDataClickSubject.asObservable(); const isActiveFromQueryParams$ = queryParams$.pipe( map<any, boolean | undefined>(p => p["active"]) ); const final$ = defer(() => { let isLoading = false; const getBandsFn$ = (isActive: boolean | undefined) => concat( of([]).pipe( tap(_ => isLoading = true), // <== here updating the outer state. map(data => ({data, isLoading: true})) ), this.#bandDataService.getBands$(isActive).pipe( map(data => ({data, isLoading: false})) ) ).pipe( finalize(() => isLoading = false) // <== again updating the outer state. ); const obs$ = merge( queryParams$.pipe(map(_ => RequestOrigin.QueryParams)), refreshDataClick$.pipe(map(_ => RequestOrigin.RefreshButton)) ).pipe( filter(requestOrigin => requestOrigin === RequestOrigin.QueryParams || (requestOrigin === RequestOrigin.RefreshButton && !isLoading)), withLatestFrom(isActiveFromQueryParams$), map(([_, isActive]) => isActive), switchMap(isActive => getBandsFn$(isActive)), startWith(this.initialState) ); return obs$; }); return final$; } } enum RequestOrigin { QueryParams, RefreshButton } interface BandState { data: Band[], isLoading: boolean } <h2>Bands</h2> <div class="row"> <div class="col-sm-12"> <div class="form-group"> <button class="btn btn-primary" type="button" (click)="refreshDataClickSubject.next()"> Refresh data </button> </div> @if(bandState$ | async; as bandState) { @if (bandState.isLoading) { Loading... } @else { <table class="table"> <thead> <tr> <th>Name</th> <th>Formation year</th> <th>Is active</th> </tr> </thead> <tbody> @for(band of bandState.data; track $index) { <tr> <td>{{ band.name }}</td> <td>{{ band.formationYear }}</td> <td>{{ band.isActive }}</td> </tr> } @empty { <h3>Empty!</h3> } </tbody> </table> } } @else { BandState$ not initialized } </div> </div> 这是一个简化版本,尽量保持变量尽可能少,以减少错误,我使用 merge 代替 combineLatest 来确保我们无需再次调用即可获得 params 最新值,然后我使用 BehaviourSubject 而不是 Subject ,它将在首次加载时触发 API。请仔细检查代码,如有任何疑问请告诉我。 ts import { ChangeDetectionStrategy, Component, DestroyRef, inject, } from '@angular/core'; import { BandDataService } from '../band-data.service'; import { BehaviorSubject, Observable, Subject, combineLatest, concat, defer, filter, finalize, map, merge, of, startWith, switchMap, tap, withLatestFrom, } from 'rxjs'; import { Band } from '../model'; import { ActivatedRoute, Params } from '@angular/router'; @Component({ selector: 'app-band-list', templateUrl: 'band-list.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class BandListComponent { bandDataService = inject(BandDataService); refreshDataClickSubject = new BehaviorSubject<string>(''); activedRoute = inject(ActivatedRoute); bandState$; constructor() { this.bandState$ = this.getBands$(); } getBands$(): Observable<Band[] | null> { const queryParams$ = this.activedRoute.queryParams; const refreshDataClick$ = this.refreshDataClickSubject.asObservable(); const isActiveFromQueryParams$: Observable<boolean> = queryParams$.pipe( map((p: Params) => <string>p['active'] === 'true') ); const final$ = defer(() => { const getBandsFn$ = (isActive: boolean | undefined) => merge(of(null), this.bandDataService.getBands$(isActive)); const obs$ = combineLatest([ isActiveFromQueryParams$, refreshDataClick$, ]).pipe( switchMap((response: Array<boolean | string>) => getBandsFn$(<boolean>response[0]) ) ); return obs$; }); return final$; } } html <h2>Bands</h2> <div class="row"> <div class="col-sm-12"> <div class="form-group"> <button class="btn btn-primary" type="button" (click)="refreshDataClickSubject.next('')" > Refresh data </button> </div> @if(bandState$ | async; as bandState) { <table class="table"> <thead> <tr> <th>Name</th> <th>Formation year</th> <th>Is active</th> </tr> </thead> <tbody> @for(band of bandState; track $index) { <tr> <td>{{ band.name }}</td> <td>{{ band.formationYear }}</td> <td>{{ band.isActive }}</td> </tr> } @empty { <h3>Empty!</h3> } </tbody> </table> } @else { Loading... } </div> </div> 堆栈闪电战
我在subscription.add中有以下场景。我不想嵌套订阅。任何建议。我想检查 Firstvalue 和 SecondValue 数据是否可用于调度操作。 这个。
我正在尝试为通过重试机制的请求添加自定义请求标头。我有一个拦截器,当前可以过滤任何特定超时的请求,同时还记录
使用 Shopify Checkout Extensions 在结帐感谢页面上访问订单 ID 或结帐令牌
我正在使用 Shopify 的结账 UI 扩展,并做出反应,在“谢谢”页面上添加“您是如何听说我们的”表单。我已经弄清楚如何渲染表单并从
下面是我的代码: this.callActiveListSubscription = 定时器(0,1000).pipe(switchMap(() => this.realtimeSupervisorHeatMapService.getLiveCallList())).subscribe((data: any) => { 控制台.log('
我继承了一个 API,它为每个端点响应返回一个自定义响应包装器对象。我正在构建一个 Angular 应用程序来从该 API 获取数据,并定义了一个类似的响应...
嗨,即使在超时后,我也想继续获取数据,我尝试了其他方法,但没有成功(timeWith、repeatWhen 等) 这是我的代码。现在,任何帮助都会很好 目标:设备停止发送...
我带来了《rxjs in action》这本书,刚刚完成测试部分。 测试 rxjs 代码与通常的测试不同,因为一切都是延迟加载。 在书中,他们提到了两个...
我正在寻找一个 RXJS 运算符,它接受值流并检查每个值是否符合特定条件。 如果此条件为真,则应忽略所有以下运算符,并且值...
AngularBehaviorSubject 在首次加载时不起作用
我在 profile.service.ts 文件中定义了一个BehaviorSubject,该文件将 false 作为初始值,并且我从 ngOnInit 函数中的 profileDialog.component.ts 组件订阅它并更新
我有一个在浏览器中运行的纯 JavaScript 应用程序。它有一些主题,有一些订阅者。我需要确保所有订阅都在眉毛之前完成吗...
React 有 useRef,它允许我保存对对象的引用。我正在尝试使用计时器开始重复调用 api。当用户点击停止时,我想停止重复调用,...
应该如何在子组件中使用/观察父 @Output() 事件发射器? 例如,在此演示中,子组件使用 @Output onGreetingChange,如下所示: 应该如何在子组件中使用/观察父级@Output()事件发射器? 例如在这个演示中子组件使用@Output onGreetingChange,如下所示: <app-greeting [greeting]="onGreetingChange | async"></app-greeting> 如果 onGreetingChange 在 AfterViewInit 生命周期钩子中发出,这将起作用。 ngAfterViewInit() { this.onGreetingChange.emit('Hola'); } 但是这会产生 ExpressionChangedAfterItHasBeenCheckedError 错误。 有没有办法让它工作而不产生错误? 我尝试在 constructor 和 OnInit 中发射。想法? 您可以使用 change detection 手动触发 detectChanges() ngAfterViewInit() { this.onGreetingChange.emit('Hola'); this.cdr.detectChanges(); } 堆栈闪电战
在 Angular 中,位置是“应用程序可以用来与浏览器 URL 交互的服务”。 它提供了一个 getState() 方法,该方法提供“位置历史记录的当前状态&