2017-03-03 74 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'。非常感谢你! –