【问题标题】:How to handle action in EmberJS in nested Component如何在嵌套组件中处理 EmberJS 中的操作
【发布时间】:2019-06-01 14:53:03
【问题描述】:

所以我在 EmberJS 中有嵌套组件,无法正确处理它们的操作。

我有路由Create 和它的模板组件pixel-grid

<div class="row">
    <div class="col-sm-7">
        {{pixel-grid}}
    </div>
    <div class="col-sm-5">

    </div>
</div>

pixel-grid 模板中,我有一个名为pixel-cell 的组件:

<table class="mx-auto">
    {{#each (range 0 panelWidth) as |row|}}
    <tr class="table-row">
        {{#each (range 0 panelHeight) as |cell|}}
        <th class="table-cell">
            {{pixel-cell onClick=(action 'changeColor')}}
        </th>
        {{/each}}
    </tr>
    {{/each}}
</table>

组件pixel-cell 有一个空模板,因为我现在不需要它。在pixel-cell 组件 js 文件中我有:

import Component from '@ember/component';
export default Component.extend({
    classNames: ['cell', 'clickable'],
    tagName: 'div',

    init() {
        this._super(...arguments);
    },
});

此代码显然无法编译,因为我没有处理此操作。 但是..

我试图在 pixel-cell 中设置操作,但后来 Ember 告诉我 pixel-grid 应该有该操作。 所以我确实将这个 changeColor 操作放入了 pixel-grid -> 这不起作用。

所以我尝试在pixel-cell js 中通过类似的方式来处理这个问题:

click() {
    this.sendAction('changeColor');
},

->那不行。

我不知道它应该如何工作;/ 我试图阅读指南,但仍然无法做到。请帮忙。

【问题讨论】:

  • Component.sendAction() 已被弃用以支持关闭操作:emberjs.com/deprecations/v3.x/#toc_ember-component-send-action

标签: javascript ember.js components action


【解决方案1】:

我建议不要处理对组件元素的操作。而是始终使用关闭操作!

如果您执行{{some-component onClick=(action 'changeColor')}},则需要在相应的changeColor 上执行操作,不是some-component 内!但是,您可能想在 some-component 中使用它,如下所示:

<button onclick={{@changeColor}}>...</button>

在您的情况下,我将为pixel-cell 组件设置tagName: '' 并添加此模板:

<div onclick={{@changeColor}}></div>

【讨论】:

    【解决方案2】:

    https://ember-twiddle.com/e04e318489bcc8e9e921e849c9fb9e9e?openFiles=templates.components.pixel-cell.hbs%2Ctemplates.components.pixel-grid.hbs

    我创建了一个 twiddle 来向您展示从父组件传递到子组件的示例操作。你可以参考上面的网址更容易理解。

    我使用了一个称为关闭操作的概念来代替 sendAction,这是 Ember 未来的规范。

    【讨论】:

      【解决方案3】:

      我个人从未使用过sendAction。相反,您应该将动作作为属性从父组件传递给子组件,然后在子组件中调用它们。这种方法更容易推理以及https://emberigniter.com/send-closure-actions-up-data-owner/ 详细解释的其他好处。

      在你的例子中:

      像素网格.js:

      export default Component.extend({
        actions: {
          changeColor(cell) {
            console.log("CELL ACTION");
            console.log(cell);
            cell.style.backgroundColor = 'red';
          }
        }
      });
      

      像素网格.hbs:

      {{pixel-cell handleColorChange=(action 'changeColor')}}
      

      pixel-cell.js:

      export default Component.extend({
          classNames: ['cell', 'clickable'],
          tagName: 'div',
      
          click: function () {
              // Invoke parent action and pass this element as the argument
              this.get("handleColorChange")(this.element);
          }
      });
      

      【讨论】:

      • 我强烈建议不要使用click 事件。
      【解决方案4】:

      好的,所以我确实设法让它工作。它看起来像这样:

      pixel-grid模板:

      <table class="mx-auto">
          {{#each (range 0 panelWidth) as |row|}}
          <tr class="table-row">
              {{#each (range 0 panelHeight) as |cell|}}
              <th class="table-cell">
                  {{pixel-cell}}
              </th>
              {{/each}}
          </tr>
          {{/each}}
      </table>
      

      pixel-cell组件js文件:

      import Component from '@ember/component';
      export default Component.extend({
          classNames: ['cell', 'clickable'],
          tagName: 'div',
      
          click: function () {
              this.sendAction('changeColor', this);
          },
      
          changeColor(cell) {
              console.log("CELL ACTION");
              console.log(cell);
              cell.element.style.backgroundColor = 'red';
          }
      });
      

      其他文件为空(pixel-gridjs 文件中只有 panelHeight 和 panel Width)。 这是一个好方法吗?

      【讨论】:

        猜你喜欢
        • 2015-10-23
        • 2015-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-05
        相关资源
        最近更新 更多