Communication entre deux modules dans AngularJs

C'est plutôt simple à imaginer, mais je n'ai trouvé aucune ressource mentionnant l'approche correcte de ce problème.

Je souhaite diffuser un événement dans un module angulaire et le recevoir dans un autre. Ces deux modules sont totalement différents, avec une base de code et un but différents. La seule chose qu'ils ont en commun est le fait qu'ils s'exécutent sur un site Web sur le même domaine (peut-être important en raison de la même politique d'origine).

Je sais que cela est possible, par exemple en synchronisant les événements via le stockage local de HTML5. Je veux juste savoir comment le faire correctement.

"Correctement"

Je commencerai par décrire l'aspect des échelles d'une application afin de clarifier ce qu'il faut mettre en œuvre pour "correctement" atteindre cet objectif.

Tout d'abord, vous avez une application qui fonctionne sur un serveur , contient un noyau qui encapsule les modules . Le niveau inférieur que vous allez à partir d'ici pourrait consister soit plus de modules ou de contrôleurs . Je traiterai les deux.

Les conditions préalables incluent, mais ne sont pas limités:

  • Mise en œuvre des événements de portée angulaire pour les contrôleurs (si nécessaire)
  • Implémentation du modèle Mediator à la spécification.
  • Mise en œuvre d'un SharedWorker avec des événements personnalisés.
  • Implémentation d'un Event-Hub côté serveur (si nécessaire)

Si vous avez besoin d'un réseau de communication entre vos contrôleurs , utilisez la norme Angular $scope & $rootScope .$broadcast $rootScope , et .$on utilitaires dans votre ( vos) module (s) – vous avez probablement déjà pensé à ceci;)

Pour communiquer entre les modules , implémentez le modèle Mediator dans votre cœur – probablement, cela sera mis en œuvre en tant que service que chaque module peut tirer; Sinon, vos modules peuvent être initialisés et fourni un bac à sable avec Mediator / Director injecté. Maintenant, vos modules dans votre application-core peuvent communiquer.

Disons que vous avez besoin de cette application / core pour communiquer avec une autre application . Mettre en place un SharedWorker avec des événements personnalisés . Vous pouvez voir un cadre, "worker.io" que j'ai construit pour UCLA ici . Le projet pourrait utiliser un certain retournement, alors n'hésitez pas à l'utiliser comme référence pour écrire le vôtre – le point sur lequel se concentrer est qu'il utilise Pseudo Port-Entanglement . C'est parce que les travailleurs n'autorisent qu'un gestionnaire de onmessage , de sorte que vous souhaitez créer un new MessageEvent ; Envoyez-le comme une chaîne JSON à l'autre port, puis JSON.parse `le message pour obtenir l'événement personnalisé et l'envoi de cet événement sur le port qui a reçu l'événement – cela vous donne des événements personnalisés. Maintenant, toute application peut utiliser ce SharedWorker et communiquer avec d'autres applications à travers elle – elle permet même de communiquer entre les onglets du navigateur .

Si vous voulez une approche plus globale d'une architecture événementielle , par exemple, pour donner aux modules sur le serveur une chance de répondre aux événements (de n'importe où) – implémentez un concentrateur d'événements sur votre serveur. Cela peut être plus qu'un projet que vous souhaitez entreprendre, mais il existe un excellent livre qui décrit comment configurer ceci: JavaScript testable, Mark Ethan Trostler .

Cela dit, il est tout à fait possible d'implémenter élégamment une architecture hautement optimisée pour les systèmes événementiels à l'aide de Mediators , SharedWorkers et EventHubs sur le back-end.

Le cadre worker.io mentionné ci-dessus utilise deux bibliothèques: Apis (Bee in latin) et Scriptorium (Hive in latin). Cependant, pour voir comment implémenter les bibliothèques, consultez le répertoire js .

J'espère que cela t'aides.

Je veux juste savoir comment le faire correctement.

«Correctement» est assez subjectif. «Correctement» est ce qui fonctionne, est facile à comprendre et est maintenable.

Cela dit, pourquoi ne pas utiliser la $window pour passer les valeurs entre les deux applications angulaires distinctes?

 function persistFoo($scope, $window) { //watch window.foo $scope.$watch(function (){ return $window.foo; }, function(v) { if($scope.foo !== v) { $scope.foo = v; } }); //watch scope.foo $scope.$watch('foo', function(v) { if($window.foo !== v) { $window.foo = v; } }); } //Module 1 app1.controller("MyCtrl1", function($scope, $window) { persistFoo($scope, $window); }); //Module 2 app2.controller("MyCtrl2", function($scope, $window) { persistFoo($scope, $window); }); 

LocalStorage fonctionnera également, si vous devez persévérer les données pour les visites ultérieures.

Je me suis heurté à un problème similaire. Voici un plunker qui montre comment résoudre un problème comme celui-ci: http://plnkr.co/edit/uk7ODSbgXfzqw0z6x4EH?p=preview

 var app1 = angular.module('App1', []); app1.controller('App1Controller', function($scope) { // use this function to send a value to app2 var sendText = function(newText) { angular.element(document.getElementById('app2')).scope().setText(newText); }; $scope.$watch('text', function(newText) { sendText(newText); }); // initial value $scope.text = "Some text"; }); /* The code above and below do not share any module, service, etc. */ var app2 = angular.module('App2', []); app2.controller('App2Controller', function($scope) { // this function will be called from app1 when text changes $scope.setText = function(newText){ $scope.$apply(function() { $scope.text = newText; }); }; });