我正在尝试学习angular2,我对如何构建数据模型提出了疑问。假设我们有一个排行榜(here is the plunker)。排行榜显示了一个玩家列表,他们的分数,以及一个复选框,表明你是否是"跟随"那个球员。玩家及其分数是从后端定义的,后端定期从服务器更新,但是"跟随"属性存储在本地。如果用户想要关注当前正在进行的游戏中该玩家正在做什么,则用户将检查该复选框。在plunker中,我们有一个LeaderboardComponent,它包含一系列LeaderboardItemComponents。 LeaderboardComponent有一个LeaderboardService,它每2秒生成一个新的Leaderboard对象。
这名侦察员表示这样做是错误的"办法。玩家姓名,分数和"跟随"属性包含在同一模型中。每2秒生成一个新的Leaderboard对象;如果选中该复选框,它将被检查直到下一次更新,然后检查将消失,因为正在创建一个全新的对象(并且服务器未提供"后跟"属性;这是特定的在客户端的用户)。应该发生的是,即使生成了新的Leaderboard对象,复选框仍将保持检查状态(并且模型将保持正确的"跟随"状态)。
我考虑的主要解决方案是将得分和名称与"完全分开"属性。它们目前都包含在LeaderboardItem模型中。我可以制作一个Followed模型,以及一个FollowedService来保持跟随玩家的名单......但是我仍然需要一个"跟随" LeaderboardItemComponent上的属性,并且在生成新的排行榜时必须手动保持与FollowedService同步。是否有更多的ng2方法来做到这一点?非常感谢你阅读这篇文章,如果我能澄清,请告诉我。我已经在下面列出了相关代码(主要是为了长度目的而不包括进口):
AppComponent:
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<h2>Leaderboard</h2>
<leaderboard>
</leaderboard>
</div>
`,
directives: [LeaderboardComponent]
})
export class App {
constructor() {
this.name = 'Angular2'
}
}
LeaderboardComponent:
@Component({
selector: 'leaderboard',
providers: [LeaderboardService],
bindings: [LeaderboardService],
template: `
<div *ngIf="loaded">
<div>
<leaderboard-item *ngFor="#li of leaderboard.items" [model]="li">
</leaderboard-item>
</div>
</div>
`,
directives: [LeaderboardItemComponent]
})
export class LeaderboardComponent {
@Input() leaderboard: Leaderboard;
loaded: boolean = false;
constructor(public leaderboardService:LeaderboardService) {
leaderboardService.getLeaderboard()
.subscribe(res => this.setLeaderboard(res));
}
setLeaderboard(leaderboard:any) {
this.leaderboard = leaderboard;
this.loaded = true;
}
}
LeaderboardItemComponent:
@Component({
selector: 'leaderboard-item',
template: `
<div>
{{model.name}}
{{model.score}}
<input type="checkbox" [(ngModel)]="model.isFollowed">
</div>
`
})
export class LeaderboardItemComponent {
@Input() model: LeaderboardItem;
constructor() {
}
}
LeaderboardService:
@Injectable()
export class LeaderboardService {
leaderboard: Leaderboard;
leaderboardStream;
constructor(public http: Http) {
this.leaderboardStream = Observable.timer(1, 2000)
.map(data => this.generateRandomLeaderboard())
}
getLeaderboard() {
return this.leaderboardStream;
}
generateRandomLeaderboard() {
this.leaderboard = new Leaderboard();
this.leaderboard.addItem(new LeaderboardItem("Player1", 1000*Math.random()))
this.leaderboard.addItem(new LeaderboardItem("Player2", 1000*Math.random()))
return this.leaderboard
}
}
排行榜(模特):
export class Leaderboard {
name: string;
items: LeaderboardItem[] = new Array();
constructor() {
this.name = "Top Players"
}
addItem(li:LeaderboardItem) {
this.items.push(li)
}
}
LeaderboardItem(模特):
export class LeaderboardItem {
name: string;
score: string;
isFollowed: boolean = false;
constructor(name:string, score:string) {
this.name = name
this.score = score
}
}