所以我在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');
},
->无效。
我不知道它应该如何工作; /我试图阅读指南,但仍然无法解决。请帮忙。
答案 0 :(得分:2)
我建议不要处理对组件元素的操作。而是总是使用关闭动作!
如果您执行{{some-component onClick=(action 'changeColor')}}
,则需要在changeColor
内相应的 not 上执行操作some-component
!但是,您可能想像这样在some-component
内部使用它:
<button onclick={{@changeColor}}>...</button>
在您的情况下,我将为tagName: ''
组件设置pixel-cell
并添加以下模板:
<div onclick={{@changeColor}}></div>
答案 1 :(得分:1)
我个人从未使用过export default Component.extend({
actions: {
changeColor(cell) {
console.log("CELL ACTION");
console.log(cell);
cell.style.backgroundColor = 'red';
}
}
});
。相反,您应该将操作作为属性从父级传递到子级组件,然后在子级组件中调用它们。这种方法以及https://emberigniter.com/send-closure-actions-up-data-owner/详尽解释的其他好处要容易得多。
在您的示例中:
pixel-grid.js:
{{pixel-cell handleColorChange=(action 'changeColor')}}
pixel-grid.hbs:
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);
}
});
pixel-cell.js:
<script src="https://polyfill.io/v2/polyfill.js?features=default,es5,es6&flags=gated,always"></script>
<script src="https://unpkg.com/@babel/standalone@7.2.5/babel.js"></script>
<script type="text/babel" data-presets="es2015,es2016,es2017,stage-3">
async function test() { return 10; }
console.log("done");
</script>
答案 2 :(得分:1)
我创建了一个旋转控件,向您展示了从父组件传递到子组件的示例动作。您可以参考上面的网址,以使其更容易理解。
我使用了一个叫做闭包动作的概念,而不是sendAction,这是Ember今后的规范。
答案 3 :(得分:0)
好,所以我确实设法使它起作用。看起来像这样:
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-grid
js文件中只有panelHeight和panel Width)。
这是这样做的好方法吗?