模型更新后视图不会更改

时间:2016-10-26 00:14:00

标签: angular angular2-template angular2-services

我正在研究一个足球项目,当我更新服务模型时,它会给我带来问题。我有两个组件(AvailablePlayers和SelectedPlayers)和两个服务(AvailablePlayersService和SelectedPlayersService)。

可用的玩家组件列出了用户可以在其中构建自定义团队的所有可用玩家。 (想想梦幻足球)选定的球员组件列出了用户从可用球员中选择的所有球员。这两种服务都只有一个硬编码模型,所以我可以测试。

我的问题是当我点击可用播放器组件中的添加按钮添加到SelectedPlayersService模型时,我希望所选播放器组件中的视图更新,但没有任何反应。我的列表正在正确填充,因此我知道服务正确地注入到组件中。

我的猜测是我需要观察模型的一些方法,但我不确定Angular 2是否具备这种能力。

可用-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
    }
} 

available-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>

选择-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',
            }],
        ];
    };
}

选择-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>

1 个答案:

答案 0 :(得分:0)

您正在两个组件装饰器中注入提供程序。这将给你两个不同的副本,这不是你想要的。您应该只在树中更高的位置注入一次服务,例如在AppComponent中,如果有的话。

此外,您的服务应将其数据公开为Observables。这样您就可以监听数据的变化。

像这样:

@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)
        );
    };
}

然后您的组件可以这样订阅:

@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
        );
    }
}

当然,您必须导入BehaviourSubject,例如import { BehaviourSubject } from 'rxjs/BehaviourSubject';