2017-09-26 40 views
1

Share data between components using a service in Angular2への質問と私が得た応答。Angular/rxjs/Subject/BehaviorSubject複数のコンポーネント間でhttpサービスデータを共有

サービスプロバイダがGET経由で取得するデータを共有しようとしています。

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(), 
}) 
} 

何ですか:

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

CustomerPortalBaseComponentは、ユーザ情報を取得するための呼び出しを行うメインルートがCustomerPortalDashboardComponentとDocumentsComponentに行くと、次のように コンポーネント構造がありますCustomerPortalDashboardComponentおよびDocumentsComponentおよびeでuserDataを取得する最善の方法他のコンポーネントが試して取得する前にデータが取得されていることを確認しますか?

答えて

0

共有サービスを使用してこれを解決しました。私はこれまで、私の共有サービスで、BehaviorSubjectの代わりにSubjectを使っていました。サブジェクトはデータをキャッシュしないので、私のデザインパターンは機能していないと思った。 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; 
} 
} 

applicationDataには、子コンポーネントに渡され、@input

を介して受信されます3210
1

いくつかのポイントは、それを動作させるために:

  1. はデータがルートに到達する前に、あなたがresolverを使用することができますロードされていることを確認するには。リゾルバはルートパスにリンクされ、ルートが解決される前にHttpリクエストを実行する関数になります。
  2. 呼び出しが完了したら、ストアにデータを格納する必要があります。 (さらに良いgetter/setter付き)すなわち、このような@Ngrxなどの外部ストアで行うことができますが、最も基本的な例は、サービス内の変数を使用することです:

例サービス:

_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; 
    } 
関連する問題