Ember2.8:从组件向控制器发送动作

时间:2016-10-08 22:49:42

标签: ember.js

阅读up on the documentation for Ember,我的印象是当一个组件触发某个操作时,它会上升到层次结构,直到它遇到具有该名称的操作。但现在发生了什么。我有一个像这样编写的游戏卡组件:

游戏card.hbs

<div class="flipper">
  <div class="front"></div>
  <div class="back">
    <img {{action "proveImAlive"}} src={{symbol}} />
  </div>
</div>

游戏card.js

import Ember from 'ember';

    export default Ember.Component.extend({
      classNames: ['flip-container'],
      actions: {
        //blank for now because testing for bubbling up
      }
    });

现在根据我所读到的内容,因为game-card.js没有“证明”这样的内容。动作,它将尝试冒泡层次结构,即特定路线的控制器。

play.js(路线/游戏)

import Ember from 'ember';

    export default Ember.Controller.extend({

      actions: {
        proveImAlive() {
          console.log('Im aliiiiveeee');
        }
      }
    });

但是当我最终运行我的应用程序时,我收到了这个错误:

Uncaught Error: Assertion Failed: <testground@component:game-card::ember483> had no action handler for: proveImAlive

现在我的问题有两个:

  1. 为什么会发生这种错误?

  2. 我希望我的一些组件操作能够冒泡到路由器的控制器。例如,当点击游戏卡时,我想将该卡的id值(将被实现)发送到控制器,以便它可以将其存储在阵列上。

    点击游戏卡 - &gt;发送值1 - >; arrayinController.push(1)

  3. 我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:4)

首先,我想指出您链接到Ember v1.10.0的文档。您应该查阅您正在使用的Ember版本的文档,您提到的是v2.8.0

  

现在根据我所读到的内容,因为game-card.js没有“证明”这样的内容。动作,它将尝试冒泡层次结构,即特定路线的控制器。

由于组件是隔离的,所以不会发生这种情况,因此没有隐式冒泡。当指南说&#34;从组件发送的动作首先转到模板的控制器&#34;并且&#34;它将冒泡到模板的路径,然后向上路由层次结构&#34;它们意味着您必须从Component明确发送操作。如果组件嵌套在另一个组件中,则必须对每个层执行此操作,直到到达Controller。

  
      
  1. 为什么会发生这种错误?
  2.   

您需要在模板中绑定操作:{{game-card proveImAlive="proveImAlive"}}

  
      
  1. 我想将该卡的id值(待实现)发送到控制器,以便将其存储在阵列上。
  2.   

我将在这部分答案中使用闭包动作。如@kumkanillam所述,它们具有更好的人体工程学,如果您查阅指南,它们是目前提出的使用操作的方法。

我为你准备了Twiddle

a)在控制器中初始化数组

export default Ember.Controller.extend({
  appName: 'Ember Twiddle',
  gameCards: null,

  init() {
    this.set('gameCards', []);
  }
}

b)实现推送到数组的动作

export default Ember.Controller.extend({
  appName: 'Ember Twiddle',
  gameCards: null,

  init() {
    this.set('gameCards', []);
  },

  actions: {
    proveImAlive(cardNo) {
      this.get('gameCards').pushObject(cardNo);
      console.log('Im aliiiiveeee - cardNo', cardNo);
    }
  }
});

c)将关闭动作绑定

{{game-card proveImAlive=(action 'proveImAlive')}}

d)触发传递参数的动作

<div class="flipper">
  <div class="front"></div>
  <div class="back">
    <button {{action proveImAlive 1}}> ProveIamAlive</button>
  </div>
</div>

答案 1 :(得分:2)

您需要显式设置操作处理程序:

{{component-name fooAction=fooHandler}}

这是必需的,因为它有助于保持组件模块化和可重用。隐式链接可能导致组件触发意外行为。

答案 2 :(得分:0)

只有将game-card组件包含在play.hbs中时,您的代码才有效。我怀疑特定路线的控制器不适用于你的情况。

以下是working-twiddle

使用关闭操作,而不是冒泡操作。为了更好地理解,您可以通过以下链接,
https://dockyard.com/blog/2015/10/29/ember-best-practice-stop-bubbling-and-use-closure-actions
http://miguelcamba.com/blog/2016/01/24/ember-closure-actions-in-depth/
https://emberigniter.com/send-action-does-not-fire/