Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 模型更新后视图不会更改_Angular_Angular2 Template_Angular2 Services - Fatal编程技术网

Angular 模型更新后视图不会更改

Angular 模型更新后视图不会更改,angular,angular2-template,angular2-services,Angular,Angular2 Template,Angular2 Services,我正在从事一个足球项目,当我更新服务模型时,它会给我带来问题。我有两个组件(AvailablePlayers和SelectedPlayer)和两个服务(AvailablePlayersService和SelectedPlayersService) available players组件列出了用户可以在其中构建自定义团队的所有可用玩家。(想象一下梦幻足球)selected players组件列出了用户从可用球员中选择的所有球员。这两个服务都只有一个硬编码的模型,所以我可以用它进行测试 我的问题是,

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

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

我的问题是,当我单击available players组件中的add按钮以添加到SelectedPlayers服务模型时,我希望selected players组件中的视图会更新,但什么也没有发生。我的列表已正确填充,因此我知道服务已正确注入组件

我想我需要看看这个模型,但我不确定Angular 2是否有这种能力

可用玩家。组件

@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
    }
} 
@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;
    }
}
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>
<div class="position-card">
    <span>Running Backs</span>
    <div *ngFor="let player of _selectedPlayers.runningBacks">
        <span class="player-name">{{ player.name }}</span>
    </div>
</div>
选定玩家。组件

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

跑回
{{player.name}

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

此外,您的服务应将其数据公开为
可观察数据。通过这种方式,您可以侦听数据中的更改

像这样:

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

当然,您必须导入行为主题,比如从'rxjs/behaviorSubject'导入{behaviorSubject}

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

此外,您的服务应将其数据公开为
可观察数据。通过这种方式,您可以侦听数据中的更改

像这样:

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

当然,您必须导入行为主题,比如从'rxjs/behaviorSubject'导入{behaviorSubject}

非常酷,从未想过像在app.component中那样将其注入更高的位置。我现在就去实施,我会回来的。谢谢你的时间!快速问题,如果我在我的
应用程序组件中注入
SelectedPlayersService
,我是否还需要将其注入可用的玩家。组件和
所选玩家。组件?刚刚实现了你的建议,我似乎无法得到它。我没有收到任何错误,当我
console.log()
selectedPlayers时,我可以看到阵列已被推送。添加所选播放机时,视图没有更新。订阅回调正在启动吗?除了在app组件中,你是否在任何地方都删除了服务注入?非常酷,从来没有想到会像在app.component中那样向上注入服务。我现在就去实施,我会回来的。谢谢你的时间!快速问题,如果我在我的
应用程序组件中注入
SelectedPlayersService
,我是否还需要将其注入可用的玩家。组件和
所选玩家。组件?刚刚实现了你的建议,我似乎无法得到它。我没有收到任何错误,当我
console.log()
selectedPlayers时,我可以看到阵列已被推送。添加所选播放机时,视图没有更新。订阅回调正在启动吗?除了在应用程序组件中,您是否删除了所有地方的服务注入?