Javascript 如何在嵌套组件中处理EmberJS中的操作

Javascript 如何在嵌套组件中处理EmberJS中的操作,javascript,ember.js,components,action,Javascript,Ember.js,Components,Action,因此,我在EmberJS中嵌套了组件,无法正确处理它们的操作 我有路径Create和它的模板组件像素网格: <div class="row"> <div class="col-sm-7"> {{pixel-grid}} </div> <div class="col-sm-5"> </div> </div> 组件像素单元有一个空模板,因为我现在不需要它。在pixel cell

因此,我在EmberJS中嵌套了组件,无法正确处理它们的操作

我有路径
Create
和它的模板组件
像素网格

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

    </div>
</div>
组件
像素单元
有一个空模板,因为我现在不需要它。在
pixel cell
component js文件中,我有:

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

    init() {
        this._super(...arguments);
    },
});
这段代码显然没有编译,因为我没有处理这个操作。 但是

我试图在
像素单元格
中设置操作,但Ember告诉我
像素网格
应该有该操作。 所以我确实把这个
changeColor
动作放在了
pixel grid
->中,但它不起作用

所以我试着在
pixel cell
js中用类似的方法来处理这个问题:

click() {
    this.sendAction('changeColor');
},
->那不行


我不知道该怎么做;/我试着阅读指南,但仍然无法做到这一点。请帮忙。

好的,所以我设法让它工作了。看起来是这样的:

<button onclick={{@changeColor}}>...</button>
像素网格
模板:

<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>
<div onclick={{@changeColor}}></div>
其他文件为空(只有
pixel grid
js文件中的panelHeight和panel Width)。
这是一种很好的方法吗?

我个人从未使用过
sendAction
。相反,您应该将动作作为属性从父组件传递给子组件,然后在子组件中调用它们。这种方法更容易推理,其他好处也更详细地解释了

在您的示例中:

pixel-grid.js:

export default Component.extend({
  actions: {
    changeColor(cell) {
      console.log("CELL ACTION");
      console.log(cell);
      cell.style.backgroundColor = 'red';
    }
  }
});
pixel-grid.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);
    }
});

我创建了一个twidle,向您展示了一个从父组件传递到子组件的示例动作。您可以参考上面的url,以便更容易理解


我没有使用sendAction,而是使用了一个称为闭包操作的概念,这是Ember未来的规范。

我建议不要处理组件元素上的操作。相反,始终使用关闭操作

如果执行
{some component onClick=(action'changeColor')}
操作,则需要在相应的
changeColor
上执行该操作,而不是在
某个组件内执行该操作!但是,您可能希望在
某些组件中使用它,如下所示:

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

我强烈建议不要使用
click
事件。
Component.sendAction()
已被弃用,取而代之的是关闭操作:emberjs.com/deprecations/v3.x/#toc_ember-Component-send-action
<div onclick={{@changeColor}}></div>