37 votes

AngularJS : passer des données entre contrôleurs

Je suis en train d'apprendre AngularJS, venant de beaucoup de frameworks MV* différents. J'aime ce framework, mais j'ai du mal à faire passer les données entre les contrôleurs.

Supposons que j'ai un écran avec une entrée (input.html) et un contrôleur, disons InputCtrl.
Il y a un bouton sur cette vue qui vous amène à un autre écran, disons d'approbation (approve.html) avec un contrôleur ApproveCtrl.
Cette ApproveCtrl a besoin des données de l'InputCtrl. Il s'agit d'un scénario très courant dans les grandes applications.

Dans mes précédents frameworks MV*, ceci était géré comme (pseudo-code) :

   var self = this;
   onClick = function() {
          var approveCtrl = DI.resolve(ApproveCtrl);
          approveCtrl.property1 = self.property1;
          approveCtrl.property1 = self.property2;
          self.router.show(approveCtrl);  
   }            
  • Cela fonctionnerait comme Controller- first. Vous créez d'abord le contrôleur, en ayant la possibilité de le mettre dans le bon état ; ensuite, la vue est créée.

Maintenant, dans AngularJS, je gère cela de la façon suivante :

 var self = this;
 onClick = function(){
          self.$locationService.path('approve');       
 }
  • Cela fonctionne comme le View-first. Vous dites à quelle vue / route vous devez naviguer, le contrôleur est créé par le framework.

Je trouve difficile de contrôler l'état du contrôleur créé et de lui transmettre des données. J'ai vu et essayé les approches suivantes, mais toutes ont leurs propres problèmes à mon avis :

  1. Injecter un service partagé dans InputCtrl & ApproveCtrl et mettre toutes les données à partager sur ce service.
    • Cela semble être une mauvaise solution ; l'état du service partagé devient un état global, alors que j'en ai juste besoin pour transmettre des données à l'ApproveCtrl.
    • La durée de vie de ce service partagé est bien plus longue que ce dont j'ai besoin - juste pour transmettre des données à l'ApproveCtrl.
  2. Passer les données dans $routeParams
    • Cela devient assez compliqué lorsque l'on doit passer beaucoup de paramètres.
  3. Utiliser les événements $scope
    • Conceptuellement, ce n'est pas quelque chose pour lequel j'utiliserais des événements - j'ai juste besoin de passer des données à l'ApproveCtrl, rien d'événementiel.
    • C'est assez compliqué ; je dois d'abord envoyer un événement au parent, qui le diffusera ensuite à ses enfants.

Est-ce que je rate quelque chose ? Est-ce que je crée trop de petits contrôleurs ?
Est-ce que j'essaie trop de m'accrocher aux habitudes des autres cadres ici ?

Merci pour votre temps,
Koen

56voto

XLII Points 508

En termes de structure, AngularJS est plus modulaire que MVC.

Le MVC classique décrit 3 couches simples qui interagissent les unes avec les autres de telle sorte que le contrôleur suture le modèle avec la vue (et le modèle ne devrait pas plutôt travailler avec la vue directement ou vice versa).

Dans Angular, vous pouvez avoir plusieurs entités, dont certaines sont totalement facultatives, qui peuvent interagir entre elles de plusieurs façons, par exemple :

Possible Interactions

C'est pourquoi il existe de multiples façons de communiquer vos données entre différentes entités. Vous pouvez :

ou

  • Envoyer des messages en utilisant le backend AJAX
  • Envoyer des messages en utilisant un système externe (tel que MQ )

...et bien d'autres encore. En raison de sa diversité, Angular permet au développeur/concepteur de choisir la méthode avec laquelle il est le plus à l'aise et de continuer. Je vous recommande de lire Guide du développeur AngularJS où vous pouvez trouver béni des solutions à certains problèmes courants.

8voto

Clay Points 1065

Si votre intention est simplement de partager des données entre deux vues, un service est probablement la meilleure solution. Si vous souhaitez persister dans un magasin de données, vous pouvez envisager une sorte de service dorsal tel qu'une API REST. Jetez un coup d'œil au service $http pour cela.

3voto

nlko Points 93

Même si XLII a donné une réponse complète, j'ai trouvé ce tutoriel en utilisant un service. C'est très intéressant et c'est un moyen simple de partager des données entre contrôleurs en utilisant la propriété "2 ways binding" : https://egghead.io/lessons/angularjs-sharing-data-between-controllers

Je ne l'ai toujours pas utilisé pour le moment.

Sinon, il y a aussi cette autre voie, basée sur les événements : http://www.objectpartners.com/2013/08/21/using-services-and-messages-to-share-data-between-controllers-in-angularjs/

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