【发布时间】:2017-06-13 02:02:50
【问题描述】:
Angular2/Typescript - 父/子指令(?)
我是 Angular2/Typescript/javascript 的新手,而且还在学习。结果,我不完全确定如何为我的问题命名。我的应用程序的基础是纸牌游戏。前提(相对于我的挣扎)是游戏有 2 个玩家,每个玩家有 5 张牌。我有 API 调用来构建/归还手牌。
在我的 app.component 模板中,我有 2 个 div 块;每个玩家的手牌一张。目前,我通过构建两个不同的卡片数组(名为 p1cards 和 p2cards)来实现它。以下是相关代码:
<div class="player1Cards" id="player1Cards">
<ul class="list-group">
<div draggable *ngFor="let card of p1cards" [dragData]="card"
class="list-group-item">
<img src="{{cardBluePath + card.fileName}}">
</div>
</ul>
</div>
<div class="player2Cards" id="player2Cards">
<ul class="list-group">
<div draggable *ngFor="let card of p2cards" [dragData]="card"
class="list-group-item">
<img src="{{cardBluePath + card.fileName}}">
</div>
</ul>
</div>
这里是整个 AppComponent 的实际导出类:
@Injectable()
export class AppComponent implements OnInit
{
@ViewChild(ModalComponent) errorMsg: ModalComponent;
errorMessage: string;
gameBoard: GameBoard[];
name: {};
mode = 'Observable';
//we need a gameboard (maybe not)
//we need an array of players
player:Player;
players:Player[] = [];
p1cards:Card[] = [];
p2cards:Card[] = [];
droppedItems = [];
//This tells us where the card images can be found
cardBluePath = "/assets/deck/Blue/";
cardRedPath = "/assets/deck/Red/";
//The boardService will handle our API calls
boardService;
//Initialize the API service
constructor(boardService:BoardService) {
this.boardService = boardService;
}
//On load...
ngOnInit()
{
//Create the game
this.boardService.createGame()
.subscribe(
error => this.errorMessage = <any>error);
//Create the players
this.createPlayer(0);
this.createPlayer(1);
}
createPlayer(player: number)
{
var playerName;
if (player == 0) {playerName = "Player1"} else {playerName = "Player2"};
//We'll make a call to the API to build the hand of cards
this.boardService.buildHand(player)
.subscribe(
cardList =>
{
var cardData = [];
cardData = JSON.parse(cardList.toString());
var i, itemLength, card
itemLength = cardData.length;
for(i=0;i<itemLength;i++)
{
let card = new Card();
Object.assign(card,
{
"cardNum":i,
"id": cardData[i].id,
"displayName": cardData[i].displayName,
"fileName": cardData[i].fileName,
"left": cardData[i].left,
"top": cardData[i].top,
"right": cardData[i].right,
"bottom": cardData[i].bottom,
"level": cardData[i].level,
"native": cardData[i].native
});
if (player == 0) {this.p1cards.push(card)} else {this.p2cards.push(card)};
////this.cards.push(card);
}
//Now we will create the player and feed it the hand
this.player = new Player(playerName);
if (player ==0) {this.player.cardHand = this.p1cards} else {this.player.cardHand = this.p2cards};
this.players.push(this.player);
}
);
}
//When a card is dropped...
onItemDrop(e: any, slot: any)
{
e.dragData.slot = slot;
//Update the object
this.boardService.playCard(slot, e.dragData.card)
.subscribe(result => {
//If the slot is open and the card is played, physically move the item
if (result == "true" )
{
this.droppedItems.push(e.dragData);
this.removeItem(e.dragData, this.p1cards);
}
else{
window.alert("Slot already occupied.");
//this.modalWindow.show()
//this.errorMsg.showErrorMessage("Slot already occupied.");
//this.errorMsg.show();
}
});
}
//Remove the card from the hand
removeItem(item: any, list: Array<any>)
{
let index = list.map((e) => {
return e.cardNum
}).indexOf(item.cardNum);
list.splice(index, 1);
}
}
createPlayer 函数实际上是问题的开始。目前,它将进行 API 调用并将 JSON 解析回卡片数组。现在,卡片数组本地存在于 AppComponent 中(作为 p1cards 或 p2cards)。
我想做的是为每个玩家创建一个玩家对象(组件),分配他们各自的手牌,然后将这些玩家放入一个数组中。我让那部分工作(部分代码仍然存在于上面,但不是全部),但我在 *ngFor 中撞墙以显示卡片。在伪代码中,我明白我需要做什么,但在实践中我无法弄清楚。
我知道 div 类 player1Cards 需要类似于“let player of Players where name = player1”,然后我需要遍历 player.cardHand[] 数组以显示每张牌。我尝试了很多东西,但没有任何效果。
然后,经过几个小时的 Google 搜索,我得出结论,我需要一个子视图供玩家处理它。我目前有以下内容:
我的 player.html 是:
<div draggable *ngFor="let card of cardHand" [dragData]="card" class="list-group-item">
<img src="{{cardBluePath + card.fileName}}">
</div>
而我的 player.ts 是:
import { Component, Input, OnInit } from '@angular/core';
import { Card } from './card';
@Component({
selector: 'player',
templateUrl: './player.html',
})
export class Player implements OnInit
{
public cardHand: Card[];
cardBluePath = "/assets/deck/Blue/";
constructor
(
public name: string
)
{}
ngOnInit()
{
}
}
然后在我的 AppComponent 模板中,我添加了块(并导入了 player.ts)
我在 App.Component 上收到一条错误消息“内联模板:69:16 原因:没有 String 的提供者!”。在我执行的所有 Google 研究和我尝试的所有更改(ViewChild、输入/输出、参考)中,我无法让它发挥作用。我不记得我到底做了什么,但有一次我能够消除错误,但卡片数组没有传递给玩家(我希望我已经提交或隐藏了该代码)。
在我看来,我理解手头的任务,但我无法实现它。我知道我需要创建 Player 对象并将其提供给相应的 cardHand 以便播放器 html 能够解析它。我可以在 AppComponent 中很好地做到这一点,但是一旦我尝试作为父母/孩子做到这一点,我就会卡住。
有人可以帮助我朝着正确的方向前进吗?
【问题讨论】:
标签: javascript angular typescript