2017-06-13 54 views
1

Angular2/Typescript - Parent/Child Directive(?)Typescript Parent/Child

我是新来的,而且还在学习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 class player1Cards需要像“让玩家的名字= player1”这样的东西,然后我需要遍历player.cardHand []数组来显示每张卡片。我尝试了很多东西,但没有成功。

因此,经过几个小时的谷歌搜索,我得出结论,我需要一个孩子的观点,供玩家来处理它。我目前拥有的为以下几点:

我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引起的错误消息:没有字符串提供程序!”。在我执行的所有Google研究中,以及我尝试过的所有更改(ViewChild,输入/输出,参考)中,我无法使其工作。我不记得我所做的是什么,但是有一次我能够消除错误,但卡阵列没有传递给玩家(我希望我已经提交或隐藏了该代码)。

在我看来,我理解手头的任务,我无法做到这一点。我知道我需要创建Player对象并为其提供各自的cardHand,以便player能够解析它。我可以在AppComponent中做到这一点,但是一旦我尝试将其作为父/子来做,我就会陷入困境。

有人可以帮助我走向正确的方向吗?

回答

0

我知道我需要创建Player对象和将其分别送给 cardHand以便玩家html能够解析它。我可以在AppComponent中做 那么好,但是一旦我尝试做它的父/子, 我卡住了。

我同意创建一个播放器对象数组,每个播放器对象都有一组卡片。事情是这样的:

let player1 = {name:'Player 1',hand:[]} 
let player2 = {name:'Player 2',hand:[]} 
this.players = [player1, player2] 

player1.hand.push(this.dealCard()) 
... 

player2.hand.push(this.dealCard()) 
... 

然后,您可以创建一个播放器组件来显示玩家(甚至是卡组件,以显示他们的手)。在您的根模板中,您将循环播放播放器,创建播放器组件并传递播放器数据(包括他们的手)。

<player-component *ngFor="let player of players" [player]="player"></player-component> 

确保您的播放器组件有一个输入端接收玩家数据:

export class PlayerComponent implements OnInit { 
@Input() player: Player; 
    constructor() { } 

    ngOnInit() { } 
} 

然后通过玩家的手<player-component>模板循环,使卡:

<p>I am {{player.name}}. My hand is:</p> 
<ul> 
    <li *ngFor="let card of player.hand">{{card}}</li> 
</ul> 

下面是一个显示工作演示的深入探索,它是此设置的简化版本: https://plnkr.co/edit/5Hz8P7poCb9Ju5IR6MWs?p=preview 您应该能够将其配置为游戏的特定设置。祝你好运!

0

如果您想访问另一个组件,请在您的播放器组件中: 1.该组件需要在顶部的导入语句 2。在@Component节中,你需要把它列入供应商 3还包括它在构造函数中

欲了解更多信息,请访问这里:https://angular.io/guide/dependency-injection