简体   繁体   English

AngularJs中两个模块之间的通信

[英]Communication between two modules in AngularJs

This is rather simple to imagine, but I haven't found any resources mentioning what is correct approach to this issue. 这很容易想象,但我没有找到任何资源提到这个问题的正确方法。

I'd like to broadcast event in one angular module and receive it in another one. 我想在一个角度模块中广播事件并在另一个角度模块中接收它。 Those two modules are totally different, with different code base and purpose. 这两个模块完全不同,具有不同的代码库和目的。 The only thing that they have in common is the fact that they are running in a website on the same domain (might be important due to the same origin policy). 他们唯一的共同点是他们在同一个域的网站上运行(由于相同的原始策略可能很重要)。

I know this is possible, for instance by synchronizing events via HTML5's Local Storage. 我知道这是可能的,例如通过HTML5的本地存储同步事件。 I just want to know how to do it properly. 我只是想知道如何正确地做到这一点。

"Properly" “正确”

I will begin by describing the aspect of scales of an application in order to provide clarity in what to implement to "properly" achieve this. 我将首先描述应用程序的比例方面,以便明确实现“正确”实现这一目标的方法。

First, You have an application that is running on a server , contains a core which encapsulates modules . 首先,您有一个在服务器上运行的应用程序 ,包含一个封装模块核心 The lower-level you go from here could consist of either more modules or controllers . 您从这里开始的较低级别可能包含更多模块控制器 I will address both. 我会解决两个问题。

Prerequisites include but are not limited too: 先决条件包括但不限于:

  • Implementing Angular scope-events for controllers (if necessary) 为控制器实现Angular 范围事件 (如有必要)
  • Implementing the Mediator Pattern to spec. 实现中介模式到规范。
  • Implementing a SharedWorker with custom events. 使用自定义事件实现SharedWorker
  • Implementing an Event-Hub on the server side (if necessary) 在服务器端实现Event-Hub (如有必要)

If you need a communication-network between your controllers , use the standard Angular $scope & $rootScope .$broadcast , .$emit , and .$on utilities inside your module(s) -- you probably already thought of this ;) 如果您需要控制器之间的通信网络,请使用标准的Angular $scope$rootScope .$broadcast.$emit.$on您的模块中的实用程序 - 您可能已经想到了这一点;)

To communicate between modules , implement the Mediator Pattern in your core -- probably, this will be implemented as a Service that each module can pull in; 要在模块之间进行通信,请在核心中实现Mediator模式 - 可能,这将作为每个模块可以引入的服务实现; otherwise, your modules can be initialized & provided a sandbox with Mediator/Director injected. 否则,您的模块可以初始化并提供注入Mediator / Director的沙箱。 Now your modules within your application-core can communicate. 现在,您的应用程序核心中的 模块可以进行通信。

Say, you need this application / core to communicate with another application . 比如说,您需要此应用程序 / 核心与另一个应用程序进行通信。 Implement a SharedWorker with custom events . 使用自定义事件实现SharedWorker You can see a framework, "worker.io" I built for UCLA here . 您可以在此处看到我为UCLA构建的框架“worker.io” The project could use some touching up, so feel free to use it as a reference to write your own -- the point to focus on is that it uses Pseudo Port-Entanglement . 该项目可以使用一些修饰,所以随意使用它作为编写自己的参考 - 重点是它使用Pseudo Port-Entanglement This is because workers only allow an onmessage handler, so you want to create a new MessageEvent ; 这是因为worker只允许onmessage处理程序,所以你想创建一个new MessageEvent ; send it as a JSON String to the other port, and then JSON.parse` the message to get the custom event and dispatch that event on the port that received the event -- this gives you custom events. 将它作为JSON字符串发送到另一个端口,然后发送JSON.parse`消息以获取自定义事件并在接收事件的端口上调度该事件 - 这为您提供了自定义事件。 Now, any application can utilize this SharedWorker and communicate to other apps through it -- it even allows for communication between browser tabs . 现在,任何应用程序都可以利用此SharedWorker并通过它与其他应用程序进行通信 - 它甚至允许浏览器选项卡之间的通信。

If you want a more global approach to an Event-Driven Architecture , say, to give modules on the server a chance to respond to events (from anywhere) -- implement an event-hub on your server. 如果您想要一种更全局化的事件驱动架构方法 ,比如说,为服务器上的模块提供响应事件的机会(从任何地方) - 在服务器上实现一个事件中心 This can be more of a project than you'd like to embark on, but a great book exists which describes how to set this up: Testable JavaScript, Mark Ethan Trostler . 这可能比你想要的项目更多,但是有一本很好的书介绍了如何设置它: 可测试的JavaScript,Mark Ethan Trostler

That said, it is completely possible to elegantly implement a highly-optimized architecture for Event-Based Systems using Mediators , SharedWorkers , and EventHubs on the back-end. 也就是说,完全可以在后端使用MediatorsSharedWorkersEventHubs优雅地为基于事件的系统实现高度优化的架构。

The worker.io framework noted above uses two libraries: Apis (Bee in latin), and Scriptorium (Hive in latin). 上面提到的worker.io框架使用了两个库: Apis (拉丁语中的Bee)和Scriptorium (拉丁语中的Hive)。 However, to see how to implement the libraries, see the js directory . 但是,要了解如何实现库,请参阅js目录

Hope this helps. 希望这可以帮助。

I just want to know how to do it properly. 我只是想知道如何正确地做到这一点。

"Properly" is pretty subjective. “正确”是非常主观的。 "Properly" is whatever works, is easy to understand and is maintainable. “正确”是任何有效的,易于理解和可维护的。

That said, why not just use $window to pass the values between the two separate running angular apps? 也就是说,为什么不使用$window来传递两个独立运行的角度应用程序之间的值?

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 will work too, if you need to persist the data for subsequent visits. 如果您需要为后续访问保留数据,localStorage也会起作用。

I stumbled about a similar problem. 我偶然发现了类似的问题。 Here is a plunker which show how to solve a problem like this: http://plnkr.co/edit/uk7ODSbgXfzqw0z6x4EH?p=preview 这是一个提示如何解决这样的问题的plunker: 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;
        });
    };

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM