Ember2.8:从父组件切换组件的布尔变量的值

时间:2016-10-09 13:57:39

标签: ember.js

我有一个游戏卡组件,设置如下:

游戏card.js

import Ember from 'ember';

export default Ember.Component.extend({
  classNames: ['flip-container'],
  isFlipped: false,
  actions: {
    doCardClick(param){
      this.get('onCardClick')(param);
    },
    toggleIsFlipped() {
      this.toggleProperty('isFlipped');
    }
  }
});

游戏card.hbs

<span {{action 'doCardClick' symbol}}>
  <div id="card" {{action 'toggleIsFlipped'}} class = "{{if isFlipped "flipped"}}">
    <figure class="front"></figure>
    <figure class="back">
      <img src={{symbol}}  />
    </figure>
  </div>
</span>

此组件与另一个名为游戏处理程序的组件交互:

游戏handler.js

import Ember from 'ember';

export default Ember.Component.extend({

  clickedCard: null,
  clickedCards: null,

  init() {
    this._super(...arguments);
    this.set('clickedCard', '');
    this.set('clickedCards', []);
  },
  handleTurn(clickedCards) {
    if(clickedCards[0] === clickedCards[1]){
      console.log('we have a matching pair!');
      this.set('clickedCards', []);
    } else {
      console.log('no match!');
      this.set('clickedCards', []);
    }
  },
  actions: {
    handleCardClick(someUrl) {
      if(this.clickedCards.length === 1){
        //we know the array will have 2 cards to evaluate now.
        this.set('clickedCard', someUrl);
        this.clickedCards.push(this.clickedCard);
        this.set('clickedCard', '');
        //we call handleTurn because we have 2 cards
        this.handleTurn(this.clickedCards);
      } else {
        // we just add the first clicked card to the array
        this.set('clickedCard', someUrl);
        this.clickedCards.push(this.clickedCard);
        this.set('clickedCard', '');
      }
    }
  }
});

并且实现如下:

游戏handler.hbs

{{#each model.cards as |instance|}}
  {{game-card symbol=instance.url onCardClick=(action 'handleCardClick')}}
{{/each}}

游戏处理程序负责处理查看两个连续点击的卡是否具有相同图像URL的逻辑。我现在要做的是以某种方式告诉单个游戏卡的isFlipped变量根据此组件执行的逻辑进行更改。

例如,在获胜对的情况下:

  1. 我们有一对获胜对(即两张具有相同图片网址的游戏卡)
  2. 游戏处理程序以某种方式隔离两张牌并传递每个属性以触发他们的'isFlipped'变量的切换。

1 个答案:

答案 0 :(得分:0)

Play.js路线中,

我假设您正在setupController挂钩中准备卡片对象,因此请将isFlipped属性包含在每个卡片实例中,默认值为false

现在,对象及其属性的所有者是播放控制器,因此在play.js控制器中更改其属性,以便此更改将通过数据绑定自动传播给所有使用者。

play.hbs

{{#each model.cards as |instance|}}
  {{game-card card=instance symbol=instance.url onCardClick=(action 'handleCardClick') toggleIsFlipped=(action 'toggleIsFlipped')}}
{{/each}}

在Play.js控制器中,

actions: {
    handleCardClick(cardInstance) {
        //use this clicked cardInstance and do your logic
    },
    toggleIsFlipped(cardInstance) {
        this.toggleProperty(cardInstance.get('isFlipped'));
        //we are chaning particular clicked instance card isFlipped property and this change will reflect it in game-card component.
    }
}

game-card.hbs

<span {{action 'doCardClick' card}}>
  <div id="card" {{action 'toggleIsFlipped' card}} class = "{{if card.isFlipped "flipped"}}">
    <figure class="front"></figure>
    <figure class="back">
      <img src={{symbol}}  />
    </figure>
  </div>
</span>

您不需要为保持状态创建父组件,您可以在相应的控制器中维护状态。旁注,
this.clickedCards.push(this.clickedCard) - 错误的 this.get('clickedCards').pushObject(this.clickedCard) - 右
请考虑get方法获取属性,pushObject代替push。如果我们只使用pushObject,那么观察者将会触发,相应的模板将使用新值进行更新。