在两个组件之间共享的服务上一次请求数据

时间:2019-04-19 10:56:08

标签: angular rxjs observable angular-httpclient

我有两个注入相同服务的组件。一个组件需要独立于另一个组件运行,但可以随时添加到另一个组件中,并且两个组件都需要相同的数据。我想避免两次加载数据(即,无论哪个组件请求数据,只需加载一次)。

共享服务:

@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...
}

第二个组件实际上与第一个组件相同,但具有与其目的相关的其他逻辑。它基本上是一个概述组件,如果尚未使用this.detailsService.loadUserDetails(user.id)加载用户的详细信息,则应获取该用户的详细信息,并使用this.detailsService.currentModel.subscribe...设置用户的详细信息,与第一个组件完全相同。

但是,问题是两次请求了数据,我想避免这种情况,只加载一次数据。我尝试将主题设置为Subject<string>,并向currentModel添加debounceTimemergeMap(id => this.userDetailsRepository.loadUserDetails(id)),但是发生了相同的事情。我怎么只能检索一次详细信息?

我还应该注意,正在使用另一个服务来检索和设置用户。该服务还在两个组件之间共享(因此它们都可以获取同一用户)。

1 个答案:

答案 0 :(得分:0)

根据以下评论进行编辑

如果可以将userDetailsS​​ubject初始化为null ...

在订阅currentModel后,在组件1中,在ngOnInit中调用loadUserDetails。 服务...

public loadUserDetails(id: string) {
    this.userDetailsSubject.next(new UserDetails())
    this.userDetailsRepository.loadUserDetails(id)
        .subscribe(details => this.userDetailsSubject.next(details));
}

ngOnInit中的组件2 ...

this.detailsService.currentModel.subscribe(details => {
        if (!details) this.loadUserDetails();
        else this.user.details = details;
    });