如何在嵌套组件中处理 EmberJS 中的操作
How to handle action in EmberJS in nested Component
所以我在 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');
},
-> 那行不通。
我不知道它应该如何工作;/我试图阅读指南,但仍然无法做到。请帮忙。
好的,所以我确实设法让它工作了。它看起来像这样:
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)。
这是执行此操作的好方法吗?
我个人从未使用过sendAction
。相反,您应该将操作作为属性从父组件传递给子组件,然后在子组件中调用它们。这种方法更容易推理以及 https://emberigniter.com/send-closure-actions-up-data-owner/ 详细解释的其他好处。
在你的例子中:
像素-grid.js:
export default Component.extend({
actions: {
changeColor(cell) {
console.log("CELL ACTION");
console.log(cell);
cell.style.backgroundColor = 'red';
}
}
});
像素-grid.hbs:
{{pixel-cell handleColorChange=(action 'changeColor')}}
像素-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);
}
});
我创建了一个 twiddle 来向您展示从父组件传递到子组件的示例操作。可以参考上面的url更容易理解
我没有使用 sendAction,而是使用了一个称为关闭操作的概念,这是 Ember 未来的规范。
我建议不要处理组件元素上的操作。而是始终使用关闭操作!
如果你做{{some-component onClick=(action 'changeColor')}}
你需要相应的动作changeColor
,不是里面的some-component
!但是你可能想像这样在 some-component
中使用它:
<button onclick={{@changeColor}}>...</button>
在你的情况下,我会为 pixel-cell
组件设置 tagName: ''
并添加此模板:
<div onclick={{@changeColor}}></div>
所以我在 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');
},
-> 那行不通。
我不知道它应该如何工作;/我试图阅读指南,但仍然无法做到。请帮忙。
好的,所以我确实设法让它工作了。它看起来像这样:
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)。
这是执行此操作的好方法吗?
我个人从未使用过sendAction
。相反,您应该将操作作为属性从父组件传递给子组件,然后在子组件中调用它们。这种方法更容易推理以及 https://emberigniter.com/send-closure-actions-up-data-owner/ 详细解释的其他好处。
在你的例子中:
像素-grid.js:
export default Component.extend({
actions: {
changeColor(cell) {
console.log("CELL ACTION");
console.log(cell);
cell.style.backgroundColor = 'red';
}
}
});
像素-grid.hbs:
{{pixel-cell handleColorChange=(action 'changeColor')}}
像素-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);
}
});
我创建了一个 twiddle 来向您展示从父组件传递到子组件的示例操作。可以参考上面的url更容易理解
我没有使用 sendAction,而是使用了一个称为关闭操作的概念,这是 Ember 未来的规范。
我建议不要处理组件元素上的操作。而是始终使用关闭操作!
如果你做{{some-component onClick=(action 'changeColor')}}
你需要相应的动作changeColor
,不是里面的some-component
!但是你可能想像这样在 some-component
中使用它:
<button onclick={{@changeColor}}>...</button>
在你的情况下,我会为 pixel-cell
组件设置 tagName: ''
并添加此模板:
<div onclick={{@changeColor}}></div>