2017-06-13 97 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