2016-10-26 4 views
1

Ich arbeite an einem Fußballprojekt, das Probleme verursacht, wenn ich ein Servicemodell aktualisiere. Ich habe zwei Komponenten (AvailablePlayers und SelectedPlayers) und zwei Dienste (AvailablePlayersService und SelectedPlayersService).Ansicht ändert sich nicht nach dem Modellupdate

Die verfügbare Player-Komponente listet alle verfügbaren Player auf, in denen ein Benutzer sein benutzerdefiniertes Team erstellen kann. (Denken Sie an Fantasy Football) Die ausgewählte Spieler-Komponente listet alle Spieler auf, die der Benutzer aus den verfügbaren Spielern ausgewählt hat. Beide Dienste haben nur ein fest codiertes Modell, mit dem ich testen kann.

Mein Problem ist, wenn ich auf die Schaltfläche Hinzufügen in der verfügbaren Player-Komponente klicken, um das SelectedPlayersService-Modell hinzuzufügen, erwarte ich die Ansicht in der ausgewählten Player-Komponente zu aktualisieren, aber nichts passiert. Meine Listen werden korrekt ausgefüllt, sodass ich weiß, dass die Dienste ordnungsgemäß in die Komponenten eingefügt werden.

Meine Vermutung ist, ich muss das Modell einige, wie, aber ich bin mir nicht sicher, ob Angular 2 diese Fähigkeit hat.

verfügbar players.component

@Component({ 
    selector: 'app-available-players', 
    templateUrl: './available-players.component.html', 
    providers: [AvailablePlayersService, SelectedPlayersService] 
}) 

export class AvailablePlayersComponent { 
    public _availablePlayers; 
    public _selectedPlayers; 

    selectPlayer = (data) => { 
     _selectedPlayers.addSelectedPlayer(data); // using running backs for testing AND I feel this is the problem 
    } 

    constructor(availablePlayers:AvailablePlayersService, selectedPlayers:SelectedPlayersService) { 
     this._availablePlayers = availablePlayers.getAvailablePlayers(); // get the available players model 
     this._selectedPlayers = selectedPlayers._selectedPlayersModel; // get the selected players model so I can add players to it 
    } 
} 

verfügbar players.component html

<div class="player-card" *ngFor="let player of _availablePlayers; let i = index"> 
    <div class="playa-data"> 
     <span class="player-name">{{ player.name }}</span> 
     <i class="fa fa-plus" (click)="selectPlayer(i, player);$event.stopPropagation()"></i> 
    </div> 
</div> 

selected-players.service

@Injectable() 
export class SelectedPlayersService { 

    public _selectedPlayersModel; 

    public addSelectedPlayer = (data) => { 
     this._selectedPlayersModel.runningBacks.push(data); 
    } 

    constructor() { 
     this._selectedPlayersModel = [ 
      runningBacks: [{ 
       id: 2, 
       imageUrl: '423.png', 
       name: 'Player Bob', 
       position: 'RB', 
      }], 
     ]; 
    }; 
} 

selected-players.component

@Component({ 
    selector: 'app-selected-players', 
    templateUrl: './selected-players.component.html', 
    providers: [SelectedPlayersService] 
}) 

export class SelectedPlayersComponent { 
    private _selectedPlayers; 

    constructor(private selectedPlayers: SelectedPlayersService) { 
     this._selectedPlayers = selectedPlayers._selectedPlayersModel; 
    } 
} 

selected-players.component html

<div class="position-card"> 
    <span>Running Backs</span> 
    <div *ngFor="let player of _selectedPlayers.runningBacks"> 
     <span class="player-name">{{ player.name }}</span> 
    </div> 
</div> 

Antwort

0

Sie sind die Anbieter in beiden der Komponenten Dekorateure zu injizieren. Dadurch erhalten Sie zwei verschiedene Kopien, was nicht Ihren Vorstellungen entspricht. Sie sollten die Dienste nur einmal an einer höheren Stelle in der Baumstruktur einfügen, z. B. in Ihrer AppComponent, sofern Sie eine haben.

Auch Ihre Dienste sollten ihre Daten als Observables offen legen. Auf diese Weise können Sie auf Änderungen in den Daten warten.

Wie so:

@Injectable() 
export class SelectedPlayersService { 

    private _selectedPlayers; 
    public selectedPlayers$; //behaviour subject observable 

    public addSelectedPlayer = (data) => { 
     this._selectedPlayers.runningBacks.push(data); 
     this.selectedPlayers$.next(
      Object.assign({}, this._selectedPlayers) 
     ); 
    } 

    constructor() { 
     this._selectedPlayers = { 
      runningBacks: [{ 
       id: 2, 
       imageUrl: '423.png', 
       name: 'Player Bob', 
       position: 'RB', 
      }], 
     }; 
     this.selectedPlayers$ = new BehaviourSubject(
      Object.assign({}, this._selectedPlayers) 
     ); 
    }; 
} 

und dann Komponenten wie diese abonnieren:

@Component({ 
    selector: 'app-selected-players', 
    templateUrl: './selected-players.component.html', 
    providers: [SelectedPlayersService] 
}) 
export class SelectedPlayersComponent { 
    private _selectedPlayers; 

    constructor(private selectedPlayers: SelectedPlayersService) { 
     this.selectedPlayers.selectedPlayers$.subscribe(
      players => this._selectedPlayer = players 
     ); 
    } 
} 

Natürlich würden Sie BehaviourSubject importieren müssen, wie import { BehaviourSubject } from 'rxjs/BehaviourSubject';

+0

Sehr cool, würde nie des Gedankens, um es höher zu injizieren wie in der app.component. Ich werde es jetzt implementieren und ich werde zurückkommen. Vielen Dank für Ihre Zeit! – Mike

+0

Schnelle Frage, wenn ich "SelectedPlayersService" in meine 'app.component' injiziere, muss ich es noch in' available-players.component' und 'selected-player.component' injizieren? – Mike

+0

Nur Ihre Vorschläge umgesetzt und ich kann es nicht bekommen. Ich bekomme keine Fehler und wenn ich 'console.log()' die ausgewähltenPlayer sehe, kann ich sehen, dass das Array verschoben wurde. Die Ansicht wird gerade nicht aktualisiert, wenn ein ausgewählter Player hinzugefügt wird. – Mike

Verwandte Themen