J'ai donc des composants imbriqués dans EmberJS et je n'arrive pas à gérer correctement leurs actions.
J'ai la route Create
et dans son modèle Component pixel-grid
:
click() { this.sendAction('changeColor'); },
In pixel -grid
modèle j'ai un composant nommé pixel-cell
:
import Component from '@ember/component'; export default Component.extend({ classNames: ['cell', 'clickable'], tagName: 'div', init() { this._super(...arguments); }, });
Le composant pixel-cell
a un modèle vide car je n'en ai pas besoin pour le moment. Dans le fichier js du composant pixel-cell
, j'ai:
<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>
Ce code ne se compile évidemment pas puisque je n'ai pas géré cette action. Mais ..
J'ai essayé de définir une action dans pixel-cell
mais Ember m'a dit que pixel-grid
devrait avoir cette action.
J'ai donc mis cette action changeColor
dans pixel-grid
-> qui ne fonctionne pas.
J'ai donc essayé de gérer cela par quelque chose comme ça dans pixel-cell
js:
<div class="row"> <div class="col-sm-7"> {{pixel-grid}} </div> <div class="col-sm-5"> </div> </div>
-> cela ne fonctionne pas.
Je n'ai aucune idée de comment cela devrait travail; / J'ai essayé de lire des guides mais je n'arrive toujours pas à gérer ça. Veuillez aider.
4 Réponses :
D'accord, j'ai donc réussi à faire fonctionner cela. Il ressemble à ceci:
pixel-grid
template:
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-cell
fichier js du composant:
<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>
Les autres fichiers sont vides (uniquement panelHeight et panel Width dans le fichier pixel-grid
js).
Est-ce une bonne façon de procéder?
Personnellement, je n'ai jamais utilisé sendAction
. Au lieu de cela, vous devez transmettre des actions en tant qu'attributs des parents aux composants enfants, puis les appeler dans les composants enfants. Cette approche est beaucoup plus facile à raisonner ainsi que d'autres avantages qui https: / /emberigniter.com/send-closure-actions-up-data-owner/ explique en détail.
Dans votre exemple:
pixel-grid.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); } });
pixel-grid.hbs:
{{pixel-cell handleColorChange=(action 'changeColor')}}
pixel-cell.js:
export default Component.extend({ actions: { changeColor(cell) { console.log("CELL ACTION"); console.log(cell); cell.style.backgroundColor = 'red'; } } });
Je déconseille fortement d'utiliser l'événement click
.
J'ai créé un twiddle pour vous montrer un exemple d'action passant du composant parent au composant enfant. Vous pouvez consulter l'url ci-dessus pour la comprendre plus facilement.
Au lieu de sendAction, j'ai utilisé un concept appelé actions de fermeture qui est la norme dans Ember à l'avenir.
Je recommanderais de ne pas gérer les actions sur les éléments des composants. Au lieu de cela, utilisez toujours des actions de fermeture!
Si vous faites {{some-component onClick = (action 'changeColor')}}
vous avez besoin de l'action changeColor
sur le correspondant, pas à l'intérieur de un composant
! Cependant, vous voudrez probablement l'utiliser dans some-component
comme ceci:
<div onclick={{@changeColor}}></div>
Dans votre cas, je définirais tagName: '' pour le composant
pixel-cell
et ajoutez ce modèle:
<button onclick={{@changeColor}}>...</button>
Component.sendAction ()
a été déconseillé au profit des actions de fermeture: emberjs.com/deprecations/v3.x/#toc_ember-component-send-acti on