【问题标题】:Ember2.8: Sending an action from a component to the controllerEmber2.8:从组件向控制器发送动作
【发布时间】:2016-10-08 22:49:42
【问题描述】:

阅读up on the documentation for Ember,我的印象是当一个动作被一个组件触发时,它会沿着层次结构向上,直到它遇到一个具有该名称的动作。但这就是现在正在发生的事情。我有一个这样写的游戏卡组件:

game-card.hbs

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

game-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 没有“proveImAlive”操作,它会尝试使层次结构冒泡,即特定路线的控制器。

play.js(路径/play)

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 值(待实现)发送到控制器,以便它可以将其存储在数组中。

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

我怎样才能做到这一点?

【问题讨论】:

    标签: ember.js


    【解决方案1】:

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

    现在根据我的阅读,由于 game-card.js 没有“proveImAlive”操作,它会尝试使层次结构冒泡,即特定路线的控制器。

    这并不完全是因为组件是隔离的,所以没有隐式冒泡。当指南说“从组件发送的动作首先进入模板的控制器”和“它会冒泡到模板的路由,然后向上路由层次结构”时,它们意味着您必须明确地从组件向上发送一个动作。如果组件嵌套在另一个组件中,则必须对每一层都执行此操作,直到到达 Controller。

    1. 为什么会出现这个错误?

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

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

    我将在这部分答案中使用闭包动作。正如@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>
    

    【讨论】:

    • 非常感谢您的解释。它让事情变得一清二楚。干杯! :-)
    【解决方案2】:

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

    {{component-name fooAction=fooHandler}}
    

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

    【讨论】:

      【解决方案3】:

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

      这里是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/

      【讨论】:

      • 嘿,我想指出你的 Twiddle 工作是因为 Ember 2.8.0 中的一个错误。如果您更新到 Ember 2.8.1,您将收到有关缺少处理程序的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多