2 votes

Ember2.8 : Envoyer une action depuis un composant vers le contrôleur

Lecture sur la documentation d'Ember J'avais l'impression que lorsqu'une action est déclenchée par un composant, elle remonte la hiérarchie jusqu'à ce qu'elle trouve une action portant ce nom. Mais voici ce qui se passe en ce moment. J'ai un composant de carte de jeu écrit comme suit :

carte de jeu.hbs

<div class="flipper">
  <div class="front"></div>
  <div class="back">
    <img {{action "proveImAlive"}} src={{symbol}} />
  </div>
</div>

carte de jeu.js

import Ember from 'ember';

    export default Ember.Component.extend({
      classNames: ['flip-container'],
      actions: {
        //blank for now because testing for bubbling up
      }
    });

Maintenant, d'après ce que j'ai lu, puisque game-card.js n'a pas d'action 'proveImAlive', il va essayer de remonter la hiérarchie, c'est-à-dire le contrôleur pour la route particulière.

play.js (la route /play)

import Ember from 'ember';

    export default Ember.Controller.extend({

      actions: {
        proveImAlive() {
          console.log('Im aliiiiveeee');
        }
      }
    });

Mais lorsque j'exécute enfin mon application, j'obtiens cette erreur :

Uncaught Error: Assertion Failed: <testground@component:game-card::ember483> had no action handler for: proveImAlive

Ma question est double :

  1. Pourquoi cette erreur se produit-elle ?

  2. Je veux que certaines des actions de mon composant remontent jusqu'au contrôleur de la route. Par exemple, lorsqu'une carte de jeu est cliquée, j'aimerais envoyer la valeur de l'identifiant (à implémenter) de cette carte au contrôleur pour qu'il puisse la stocker dans un tableau.

    la carte de jeu est cliquée --> envoie la valeur 1 --> arrayinController.push(1)

Comment puis-je y parvenir ?

4voto

locks Points 755

Tout d'abord, j'aimerais souligner que vous avez fait un lien vers la documentation d'Ember v1.10.0. Vous devriez consulter la documentation de la version d'Ember que vous utilisez, qui est, comme vous le dites, la suivante v2.8.0 .

D'après ce que j'ai lu, comme game-card.js n'a pas d'action "proveImAlive", il va essayer de remonter la hiérarchie, c'est-à-dire le contrôleur de la route en question.

Ce n'est pas tout à fait ce qui se passe car les composants sont isolés, il n'y a donc pas de bouillonnement implicite. Lorsque les guides précisent que "les actions envoyées par les composants vont d'abord au contrôleur du modèle" et que "les bulles sont dirigées vers la route du modèle, puis vers le haut de la hiérarchie des routes", cela signifie que vous devez explicitement envoyer une action vers le haut à partir du composant. Si le composant est imbriqué dans un autre composant, vous devez le faire pour chaque couche, jusqu'à ce que vous atteigniez le contrôleur.

  1. Pourquoi cette erreur se produit-elle ?

Vous devez lier l'action dans le modèle : {{game-card proveImAlive="proveImAlive"}}

  1. j'aimerais envoyer la valeur de l'identifiant (à implémenter) de cette carte au contrôleur pour qu'il puisse la stocker dans un tableau.

Je vais utiliser des actions de fermeture pour cette partie de la réponse. Comme mentionné par @kumkanillam, elles ont une meilleure ergonomie, et elles sont la façon actuellement proposée pour utiliser les actions si vous consultez les Guides.

J'ai préparé un Twiddle pour vous.

a) Initialiser le tableau dans le contrôleur

export default Ember.Controller.extend({
  appName: 'Ember Twiddle',
  gameCards: null,

  init() {
    this.set('gameCards', []);
  }
}

b) Implémenter l'action qui pousse vers le tableau

export default Ember.Controller.extend({
  appName: 'Ember Twiddle',
  gameCards: null,

  init() {
    this.set('gameCards', []);
  },

  actions: {
    proveImAlive(cardNo) {
      this.get('gameCards').pushObject(cardNo);
      console.log('Im aliiiiveeee - cardNo', cardNo);
    }
  }
});

c) Lier l'action de fermeture vers le bas

{{game-card proveImAlive=(action 'proveImAlive')}}

d) Déclencher l'action en passant les arguments

<div class="flipper">
  <div class="front"></div>
  <div class="back">
    <button {{action proveImAlive 1}}> ProveIamAlive</button>
  </div>
</div>

2voto

maffews Points 384

Vous devez définir explicitement le gestionnaire d'action :

{{component-name fooAction=fooHandler}}

Cela est nécessaire car cela permet de garder les composants modulaires et réutilisables. Les liens implicites peuvent avoir pour conséquence qu'un composant déclenche un comportement involontaire.

0voto

Ember Freak Points 11453

Votre code devrait fonctionner, seulement si vous avez inclus game-card dans play.hbs . Je doute que le contrôleur pour la route particulière ne joue pas dans votre cas.

Voici le travailler-twiddle

Au lieu d'actions de bulles, utilisez des actions de fermeture. Pour mieux comprendre, vous pouvez consulter les liens ci-dessous,
https://dockyard.com/blog/2015/10/29/ember-best-practice-stop-bubbling-and-use-closure-actions
http://miguelcamba.com/blog/2016/01/24/ember-closure-actions-in-depth/
https://emberigniter.com/send-action-does-not-fire/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X