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

Gia*_*lvá 3 ember.js

阅读Ember 的文档后,我的印象是,当组件触发某个操作时,它将沿着层次结构向上移动,直到遇到具有该名称的操作。但这就是现在正在发生的事情。我有一个游戏卡组件,如下所示:

游戏卡.hbs

<div class="flipper">
  <div class="front"></div>
  <div class="back">
    <img {{action "proveImAlive"}} src={{symbol}} />
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

游戏卡.js

import Ember from 'ember';

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

现在根据我读到的内容,由于 game-card.js 没有“proveImAlive”操作,因此它将尝试向上冒泡层次结构,即特定路由的控制器。

play.js(路线 /play)

import Ember from 'ember';

    export default Ember.Controller.extend({

      actions: {
        proveImAlive() {
          console.log('Im aliiiiveeee');
        }
      }
    });
Run Code Online (Sandbox Code Playgroud)

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

Uncaught Error: Assertion Failed: <testground@component:game-card::ember483> had no action handler for: proveImAlive
Run Code Online (Sandbox Code Playgroud)

现在我的问题有两个:

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

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

    单击游戏卡 --> 发送值 1 --> arrayinController.push(1)

我怎样才能实现这个目标?

loc*_*cks 5

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

现在根据我读到的内容,由于 game-card.js 没有“proveImAlive”操作,因此它将尝试向上冒泡层次结构,即特定路由的控制器。

这并不是真正发生的情况,因为组件是隔离的,因此不存在隐式冒泡。当指南说“从组件发送的操作首先进入模板的控制器”和“它将冒泡到模板的路由,然后沿着路由层次结构向上”时,它们意味着您必须显式地从组件向上发送操作。如果组件嵌套在另一个组件内,则必须对每一层执行此操作,直到到达控制器。

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

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

  1. 我想将该卡的 id 值(要实现)发送到控制器,以便它可以将其存储在数组中。

我将在这部分答案中使用关闭操作。正如 @kumkanillam 所提到的,它们具有更好的人体工程学原理,如果您查阅指南,它们是当前建议的使用操作的方式。

我为你准备了一个Twiddle

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

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

  init() {
    this.set('gameCards', []);
  }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

c) 绑定关闭动作

{{game-card proveImAlive=(action 'proveImAlive')}}
Run Code Online (Sandbox Code Playgroud)

d) 传递参数触发动作

<div class="flipper">
  <div class="front"></div>
  <div class="back">
    <button {{action proveImAlive 1}}> ProveIamAlive</button>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)