【问题标题】:Angular2 - one store, multiple component, different API callAngular2 - 一个商店,多个组件,不同的 API 调用
【发布时间】:2017-07-24 01:09:32
【问题描述】:

假设我有一个父组件HomeComponent,有多个嵌套组件TeamsStandingComponentTeamsStandingComponent 必须显示从 API 调用收集的数据,使用公共但私有的存储区 TeamsStandingStore

现在我将向您展示我的代码。

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

【问题讨论】:

    标签: angular components rxjs store


    【解决方案1】:

    我相信所有嵌套组件都获得相同的值,因为它们都使用TeamStandingStore 的相同实例。

    您没有在提供TeamStandingStore 的位置显示您的模块,但我猜您将其作为模块级别提供。这意味着每个组件都获得相同的 Store 实例,因此都订阅相同的 standings observable。

    在这种情况下,您可能想要做的是在组件级别而不是模块级别提供 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;
      }
    

    【讨论】:

    • 是的,我忘了在这里复制 NgModule 代码。当然我在那里公开TeamStandingStore。是的,您的解决方案就像一个魅力,我在TeamsStandingComponent providers 数组中添加了TeamStandingStore。非常感谢!
    猜你喜欢
    • 2016-03-23
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多