在两个组件之间共享的服务上请求一次数据
Request data once on a service shared between two components
我有两个注入相同服务的组件。一个组件需要独立于另一个组件运行,但可以随时添加到另一个组件,并且两个组件需要相同的数据。我想避免数据被加载两次(即无论哪个组件请求数据,只加载一次)。
共享服务:
@Injectable()
export class UserDetailsService {
private userDetailsSubject: BehaviorSubject<UserDetails> = new BehaviorSubject<UserDetails>(new UserDetails());
public currentModel: Observable<UserDetails> = this.userDetailsSubject.asObservable();
constructor(private userDetailsRepository: UserDetailsRepository) {}
public loadUserDetails(id: string) {
// loadUserDetails makes a HttpClient get call which returns the result as an Observable
this.userDetailsRepository.loadUserDetails(id)
.subscribe(details => this.userDetailsSubject.next(details));
}
}
第一部分:
export class UserLookupComponent implements OnInit {
// Other logic ...
// The user is loaded via lookup.
public user: User;
constructor(private detailsService: UserDetailsService) {}
public loadUserDetails() {
this.detailsService.loadUserDetails(user.id);
}
ngOnInit() {
this.detailsService.currentModel.subscribe(details => {
this.user.details = details;
});
}
// Other logic...
}
第二个组件实际上与第一个组件相同,只是与其用途相关的其他逻辑不同。它基本上是一个 Overview 组件,如果用户尚未使用 this.detailsService.loadUserDetails(user.id)
加载,它应该获取用户的详细信息,并使用 this.detailsService.currentModel.subscribe...
设置用户的详细信息,与第一个组件完全相同。
然而,问题是数据被请求了两次,我想避免这种行为,只加载一次数据。我已经尝试将主题设置为 Subject<string>
,并向 currentModel 添加 debounceTime
和 mergeMap(id => this.userDetailsRepository.loadUserDetails(id))
,但同样的事情发生了。我怎样才能只检索一次详细信息?
我还应注意,正在使用另一项服务检索和设置用户。此服务也在两个组件之间共享(因此它们都可以获得相同的用户)。
根据以下评论编辑
如果可以将 userDetailsSubject 初始化为 null...
在组件 1 中,在订阅 currentModel 后调用 ngOnInit 中的 loadUserDetails。
服务...
public loadUserDetails(id: string) {
this.userDetailsSubject.next(new UserDetails())
this.userDetailsRepository.loadUserDetails(id)
.subscribe(details => this.userDetailsSubject.next(details));
}
组件 2...在 ngOnInit...
this.detailsService.currentModel.subscribe(details => {
if (!details) this.loadUserDetails();
else this.user.details = details;
});
我有两个注入相同服务的组件。一个组件需要独立于另一个组件运行,但可以随时添加到另一个组件,并且两个组件需要相同的数据。我想避免数据被加载两次(即无论哪个组件请求数据,只加载一次)。
共享服务:
@Injectable()
export class UserDetailsService {
private userDetailsSubject: BehaviorSubject<UserDetails> = new BehaviorSubject<UserDetails>(new UserDetails());
public currentModel: Observable<UserDetails> = this.userDetailsSubject.asObservable();
constructor(private userDetailsRepository: UserDetailsRepository) {}
public loadUserDetails(id: string) {
// loadUserDetails makes a HttpClient get call which returns the result as an Observable
this.userDetailsRepository.loadUserDetails(id)
.subscribe(details => this.userDetailsSubject.next(details));
}
}
第一部分:
export class UserLookupComponent implements OnInit {
// Other logic ...
// The user is loaded via lookup.
public user: User;
constructor(private detailsService: UserDetailsService) {}
public loadUserDetails() {
this.detailsService.loadUserDetails(user.id);
}
ngOnInit() {
this.detailsService.currentModel.subscribe(details => {
this.user.details = details;
});
}
// Other logic...
}
第二个组件实际上与第一个组件相同,只是与其用途相关的其他逻辑不同。它基本上是一个 Overview 组件,如果用户尚未使用 this.detailsService.loadUserDetails(user.id)
加载,它应该获取用户的详细信息,并使用 this.detailsService.currentModel.subscribe...
设置用户的详细信息,与第一个组件完全相同。
然而,问题是数据被请求了两次,我想避免这种行为,只加载一次数据。我已经尝试将主题设置为 Subject<string>
,并向 currentModel 添加 debounceTime
和 mergeMap(id => this.userDetailsRepository.loadUserDetails(id))
,但同样的事情发生了。我怎样才能只检索一次详细信息?
我还应注意,正在使用另一项服务检索和设置用户。此服务也在两个组件之间共享(因此它们都可以获得相同的用户)。
根据以下评论编辑
如果可以将 userDetailsSubject 初始化为 null...
在组件 1 中,在订阅 currentModel 后调用 ngOnInit 中的 loadUserDetails。 服务...
public loadUserDetails(id: string) {
this.userDetailsSubject.next(new UserDetails())
this.userDetailsRepository.loadUserDetails(id)
.subscribe(details => this.userDetailsSubject.next(details));
}
组件 2...在 ngOnInit...
this.detailsService.currentModel.subscribe(details => {
if (!details) this.loadUserDetails();
else this.user.details = details;
});