Angular - 组件使用 BehaviourSubject 进行重复的 api 'GET' 请求

问题描述 投票:0回答:1

我正在开发一个 Angular v14 应用程序,但我无法弄清楚如何解决我的组件进行重复 api 调用的问题。

我有一个在所有组件之间共享的服务,用于设置和检索状态值。 api 调用所需的值设置了一个初始值,以便在组件初始化时能够发出请求。

@Injectable()
export class SharedService {
  private type$ = new BehaviorSubject<string>('some-tab-value');

  setType(type: string) {
    this.type$.next(libraryType);
  }

  getType() {
    return this.type$.asObservable();
  }
}

我有一个顶级组件,每当用户单击页面上带有选项卡值的选项卡时,它都会设置BehaviorSubject值;

import { SharedService } from './services/shared.service';

export class TopLevelComponent {
  private initialValue = 'some value';

  constructor(private sharedService: SharedService) {}

  onTabClick(type) {
    this.sharedService.setType(type);
  }
}

我有另一个组件订阅在顶级组件中单击的选项卡值。需要进行api调用。

import { SharedService} from '../../services/shared.service';
import { SomeService } from './services/some.service';

export class SomeOtherComponent implements OnInit {
  constructor(private sharedService: SharedService, private someService: SomeService) {}
  
  ngOnInit() {
    this.sharedService.getType().pipe(
      switchMap(selectedType => {
        // some api call
        return this.someService.getStuff(selectedType)
      })
    ).subscribe(value => {
       // this value is always logging twice when the component loads
       // also logs twice when clicking on tab in UI
       console.log(value)
     )
  }
}

处理 http 请求的服务看起来像这样

import { HttpClient } from '@angular/common/http';

@Injectable()
export class SomeService {
  constructor(private httpClient: HttpClient) {}

  getStuff(type) {
    return this.httpClient.get('some-url').pipe(
      catchError(err => {
        return throwError(() => new Error('Error while fetching stuff: ' + err));
      }
    )
  }

}

我认为这与BehaviorSubject 发出最后一个和当前值有关。我尝试将BehaviorSubject 切换为Subject。但是,由于主题不采用初始值,因此我尝试在顶级组件内的 ngOnInit 函数中设置初始值。在用户单击选项卡之前,另一个组件不会触发 http 请求(但我希望它在初始化时也触发)。

我觉得这应该是一个简单的解决方案,但我一直在努力解决这个问题。任何帮助表示赞赏。谢谢

javascript angular rxjs angular-observable
1个回答
0
投票

当组件被销毁时,请确保取消对 BehaviourSubject 的订阅,否则即使组件被销毁,它也会继续存在并导致内存泄漏。

import { SharedService} from '../../services/shared.service';
import { SomeService } from './services/some.service';

export class SomeOtherComponent implements OnInit {
  private sub: Subscription = new Subscription();
  constructor(private sharedService: SharedService, private someService: SomeService) {}
  
  ngOnInit() {
    this.sub.add(
      this.sharedService.getType().pipe(
        switchMap(selectedType => {
          // some api call
          return this.someService.getStuff(selectedType)
        })
      ).subscribe(value => {
         // this value is always logging twice when the component loads
         // also logs twice when clicking on tab in UI
         console.log(value)
      })
    );
  }
  
  ngOnDestroy() {
    this.sub.unsubscribe();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.