1
votes

Comment gérer l'action dans EmberJS dans un composant imbriqué

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.


1 commentaires

Component.sendAction () a été déconseillé au profit des actions de fermeture: emberjs.com/deprecations/v3.x/#toc_ember-component-send-acti‌ on


4 Réponses :


0
votes

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?


0 commentaires

0
votes

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';
    }
  }
});


1 commentaires

Je déconseille fortement d'utiliser l'événement click .



1
votes

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

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.


0 commentaires

1
votes

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>


0 commentaires