Angular/rxjs/Subject/BehaviorSubject跨多个组件共享http服务数据

Angular/rxjs/Subject/BehaviorSubject跨多个组件共享http服务数据

问题描述:

后续问题至Share data between components using a service in Angular2以及我得到的响应。Angular/rxjs/Subject/BehaviorSubject跨多个组件共享http服务数据

我试图共享服务提供程序通过GET检索的数据。 组件结构与主要路线要CustomerPortalDashboardComponent和DocumentsComponent

<CustomerPortalBaseComponent> 
<router-outlet> 
    <CustomerPortalDashboardComponent/> 
    <DocumentsComponent/> 
<router-outlet> 
</CustomerPortalBaseComponent> 

CustomerPortalBaseComponent进行调用,以获取用户信息如下:

ngOnInit() { 
this.customerPortalUserService.getUserInfo() 
    .subscribe(
    (event: HttpEvent<any>) => { 
     switch (event.type) { 
     case HttpEventType.Sent: 
      break; 
     case HttpEventType.Response: 
      this.handleUserData(event.body) 

     } 
    }, 
    (err: HttpErrorResponse) => { 
     if (err.error instanceof Error) { 
     console.log("Client-side error occured."); 
     } else {   
     console.log("Server-side error occured."); 
     } 
    } 
) 
} 
handleUserData(data: any){ 
    this.userData = data; 
} 

CustomerPortalUserService

getUserInfo(){ 
interface ItemsResponse { 
    results: string[]; 
} 
return this.http.get<ItemsResponse>(this.userUrl, { 
    observe: 'response', 
    headers: new HttpHeaders().set(), 
}) 
} 

什么在CustomerPortalDashboardComponent和DocumentsComponent和e中获取userData的最佳方法确保数据在其他组件尝试获取之前已被检索?

通过使用共享服务解决了这个问题。我之前是这样做的,但是在我的共享服务中,我使用的是Subject而不是BehaviorSubject。主题不缓存数据,所以我认为我的设计模式不起作用。当更改为BehaviorSubject时,一切都很完美。

CustomerPortalBaseComponent对将通过此应用程序模块共享的数据进行所有HTTP调用。然后它将消息发送到共享服务,其他组件(路由的主要组件)订阅该服务。 EX:

CustomerPortalBaseComponent

this.applicationsMessagingService.sendMessage(data) 

ApplicationsMessagingService:然后

Injectable() 
export class ApplicationsMessagingService { 

    private subject = new BehaviorSubject<any>(null); 

    sendMessage(message: {}) { 
    this.subject.next(message); 
    } 

    clearMessage() { 
    this.subject.next(null); 
} 

    getMessage(): Observable<any> { 
    return this.subject.asObservable(); 
    } 

} 

CustomerPortalDashboardComponent

ngOnInit() { 
this.subscription = this.applicationsMessagingService.getMessage().subscribe(message => { 
    this.message = message; 
    this.handleApplicationData(this.message); 
}); 


handleApplicationData(data: any){ 
    if (data){ 
    this.applicationData = data; 
} 
} 

应用 - 被传递给子组件,并通过@input

收到3210

几点,使其工作:

  1. 为了确保数据加载都达到了之前的路线,你可以使用一个resolver。解析器将链接到您的路由路径,并且将成为在解析路由之前执行Http请求的函数。
  2. 拨打电话后,您需要将数据存储在商店中。可与外部存储装置,如@Ngrx来完成,但最基本的例子是使用你的服务(甚至更好getter/setter)内的变量:

例如服务:

_equipmentDetails: any // Should be private in use-case 

... 

getEquipmentDetail(clientId, modemId): Observable<any> { 
    const url = 'myOwnUrl'; 

    return this.Http 
    .get(url) 
    .map(result => { 
     if (result) { 
     // Notice how I set the value from the Http call. 
     return this._equipmentDetails = result.json(); 
     } 
    }) 
    .catch(this.handleError); 
} 

然后您可以通过依赖注入从组件获取属性值。

constructor(
    ... 
    private equipmentService: ServiceClass, 
) { 
    this.equipmentService._equipmentDetails; 
    }