14

这很容易想象,但我还没有找到任何资源提到解决这个问题的正确方法。

我想在一个角度模块中广播事件并在另一个模块中接收它。这两个模块完全不同,具有不同的代码库和用途。它们唯一的共同点是它们在同一域的网站中运行(由于相同的来源策略可能很重要)。

我知道这是可能的,例如通过 HTML5 的本地存储同步事件。我只是想知道如何正确地做到这一点。

4

3 回答 3

6

“适当地”

我将首先描述应用程序的规模方面,以便清楚地说明要“正确”实现这一目标的实现方式。

首先,您有一个在服务器上运行的应用程序,其中包含一个封装模块的核心。您从这里开始的较低级别可能包含更多模块控制器。我将解决这两个问题。

先决条件包括但不限于:

  • 为控制器实现 Angular范围事件(如有必要)
  • 根据规范实现中介者模式。
  • 使用自定义事件实现SharedWorker
  • 在服务器端实现Event-Hub(如有必要)

如果您需要控制器之间的通信网络,请在模块中使用标准的 Angular $scope& $rootScope .$broadcast.$emit.$on实用程序——您可能已经想到了这一点;)

要在模块之间进行通信,请在您的核心中实现中介者模式——可能,这将实现为每个模块都可以引入的服务;否则,您的模块可以被初始化并提供一个注入了Mediator/Director的沙箱。现在您的应用程序核心中的模块可以通信了。

说,您需要此应用程序/核心与另一个应用程序进行通信。使用自定义事件实现SharedWorker。您可以在这里看到我为 UCLA 构建的框架“worker.io”。该项目可能需要一些修饰,因此请随意将其用作编写自己的参考 -重点是它使用Pseudo Port-Entanglement。这是因为工人只允许一个onmessage处理程序,所以你想创建一个new MessageEvent; 将其作为 JSON 字符串发送到另一个端口,然后 JSON.parse` 消息以获取自定义事件并在接收事件的端口上调度该事件 - 这为您提供自定义事件。现在,任何应用程序都可以利用这个SharedWorker并通过它与其他应用程序进行通信——它甚至允许在浏览器选项卡之间进行通信。

如果您想要一种更全局的事件驱动架构方法,例如,让服务器上的模块有机会(从任何地方)响应事件——在您的服务器上实现一个事件中心。这可能更像是一个项目,而不是您想开始的,但是有一本很棒的书描述了如何设置它:可测试的JavaScript,Mark Ethan Trostler

也就是说,完全有可能在后端使用MediatorsSharedWorkersEventHubs为基于事件的系统优雅地实现高度优化的架构。

上面提到的worker.io框架使用两个库:Apis(拉丁语中的Bee)和Scriptorium(拉丁语中的Hive)。但是,要查看如何实现库,请参阅js 目录

希望这可以帮助。

于 2014-12-08T19:36:52.030 回答
5

我只是想知道如何正确地做到这一点。

“正确”是相当主观的。“正确”是指任何有效、易于理解且可维护的方法。

也就是说,为什么不直接使用$window在两个单独运行的 Angular 应用程序之间传递值呢?

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 也可以使用。

于 2013-02-28T19:36:39.433 回答
-1

我偶然发现了一个类似的问题。这是一个 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;
        });
    };

});
于 2013-04-26T22:25:26.187 回答