我正在开发一个 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 请求(但我希望它在初始化时也触发)。
我觉得这应该是一个简单的解决方案,但我一直在努力解决这个问题。任何帮助表示赞赏。谢谢
当组件被销毁时,请确保取消对 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();
}
}