2017-03-03 76 views
1

比方說,我有一個父組件HomeComponent,它具有多個嵌套組件,TeamsStandingComponentTeamsStandingComponent必須使用通用的私人商店TeamsStandingStore顯示從API調用收集的數據。Angular2 - 一個商店,多個組件,不同的API調用

現在我會告訴你我的代碼。

HomeComponent

import { Component } from '@angular/core'; 

@Component({ 
    selector: 'home', 
    templateUrl: '../templates/home.html' 
}) 
export class HomeComponent { 
    constructor(
) {} 
} 

這是HomeComponent模板:

<div class="top-three-standings__wrapper"> 
    <teams-standing #standing1 [leagueId]="426"></teams-standing> 
    <teams-standing #standing2 [leagueId]="439"></teams-standing> 
</div> 

這是TeamsStandingComponent

import { Component, AfterViewInit, NgZone, ChangeDetectorRef, 
    ElementRef, Input } from '@angular/core'; 

import { TeamsStandingStore } from '../stores/teams-standing'; 
import { HttpClient } from '../services/http-client'; // you can ignore this 

@Component({ 
    selector: 'teams-standing', 
    providers: [HttpClient], // you can ignore this 
    templateUrl: '../templates/teams-standing.html' 
}) 
export class TeamsStandingComponent implements AfterViewInit { 

    @Input() private teams: Object; 
    @Input() private leagueId: string; 
    private teamsStandingStore: TeamsStandingStore; 

    constructor(
    private TeamsStandingStore: TeamsStandingStore, 
    private ngzone: NgZone, 
    private cdref: ChangeDetectorRef 
) { 
    console.clear(); 
    this.teamsStandingStore = TeamsStandingStore; 
    } 

    public ngAfterViewInit() { 
    this.ngzone.runOutsideAngular(() => { 

     this.teamsStandingStore.standings 
     .subscribe((data) => { 
      this.teams = data; 
      this.cdref.detectChanges(); 
     }); 
    }); 

    this.http.get(`competitions/` + this.leagueId + `/leagueTable`) 
     .subscribe(
     (data: any) => this.teamsStandingStore.showStandings(data.json()), 
     (error) => console.log(error) 
    ); 
    } 

} 

這是TeamsStandingComponent模板:

<div class="teams-standing__table"> 
    <h2>{{leagueId}} - {{teams?._links?.competition?.href}}</h2> 
    <h3>{{teams?.leagueCaption}}</h3> 
    <div *ngFor="let team of teams?.standing"> 
    {{team.teamName}} 
    {{team.crestURI}} 
    </div> 
</div> 

最後這是TeamStandingStore

import { Injectable } from '@angular/core'; 
import { Subject } from 'rxjs/Rx'; 

@Injectable() 
export class TeamsStandingStore { 

    private standings: Subject<any> = new Subject<any>(); 
    private showStands: Subject<any> = new Subject<any>(); 

    constructor() { 
    this.showStands 
     .subscribe(this.standings); 
    } 

    public showStandings(standings) { 
    this.showStands.next(standings); 
    } 

} 

我的問題是,這些嵌套的組件,TeamsStandingComponent,顯示相同的數據,即使組件調用不同的端點 - ,你可以見 - 並有不同的迴應。

PS:我使用@angular v.2.4.9和rxjs v.5.0.2

回答

0

我相信所有的嵌套的組件,因爲它們都使用TeamStandingStore的同一個實例得到相同的值。

你不顯示你的模塊在哪裏提供TeamStandingStore,但我猜你提供它作爲模塊級別。這意味着每個組件都獲得相同的Store實例,因此所有訂閱都可以觀察到相同的standings

在這種情況下您可能要做的是在組件級別而不是在模塊級別提供Store,因此每個TeamStandingComponent都有它自己的實例。您將通過提供組件裝飾的TeamStandingStore這樣做:

@Component({ 
    selector: 'teams-standing', 
    providers: [HttpClient, TeamStandingStore], // <- insert TeamStandingStore here 
    templateUrl: '../templates/teams-standing.html' 
}) 
export class TeamsStandingComponent implements AfterViewInit { 

    @Input() private teams: Object; 
    @Input() private leagueId: string; 
    private teamsStandingStore: TeamsStandingStore; 

    constructor(
    private TeamsStandingStore: TeamsStandingStore, 
    private ngzone: NgZone, 
    private cdref: ChangeDetectorRef 
) { 
    console.clear(); 
    this.teamsStandingStore = TeamsStandingStore; 
    } 
+0

是的,我忘了這裏複製NgModule代碼。當然,我在那裏展示了'TeamStandingStore'。是的,你的解決方案就像一個魅力,我已經在'TeamsStandingComponent'提供者數組中添加了'TeamStandingStore'。非常感謝你! –