【问题标题】:Request data once on a service shared between two components在两个组件之间共享的服务上请求一次数据
【发布时间】:2019-04-19 10:56:08
【问题描述】:

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

共享服务:

@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&lt;string&gt;,并将debounceTimemergeMap(id =&gt; this.userDetailsRepository.loadUserDetails(id)) 添加到currentModel,但同样的事情发生了。我怎样才能只检索一次详细信息?

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

【问题讨论】:

    标签: angular rxjs observable angular-httpclient


    【解决方案1】:

    根据以下cmets编辑

    如果可以将 userDetailsS​​ubject 初始化为 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;
        });
    

    【讨论】:

    • 这只会加载一次数据,永远不会再次加载。如果我对新用户执行查找,它应该会获取该新用户的详细信息一次,该详细信息与其他组件共享,但它不会在您的解决方案中执行此操作。
    • @driima,那么您发起新请求的条件是什么?
    • 组件 1(查找组件)在加载用户时请求用户详细信息。组件 2(用户概述)仅应在未加载时请求用户详细信息。两个组件都可以通过共享服务访问用户,但组件 2 可以独立于组件 1 使用(即,它可以自己加载用户......组件 2 可以在另一个页面中使用而无需组件 1,并且应该能够在发生此类事件时加载用户详细信息)。
    • @driima,所以您希望组件 1 始终加载,但组件 2 仅在没有数据的情况下加载?还是仅在组件 1 不活动时才加载组件 2?
    • @TzannetosPhilippakos 第一个 - 1 始终加载数据,2 仅在没有数据时加载。
    猜你喜欢
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    相关资源
    最近更新 更多