这很容易想象,但我没有找到任何资源提到这个问题的正确方法。
我想在一个有角度的模块中广播事件,然后在另一个模块中接收它。这两个模块完全不同,具有不同的代码库和目的。他们唯一的共同点是他们在同一个域名的网站上运行(由于相同的原始政策可能很重要)。
我知道这是可能的,例如通过HTML5的本地存储同步事件。我只是想知道如何正确地做到这一点。
答案 0 :(得分:6)
我将首先描述应用程序 scales 的方面,以便明确实现“正确”实现的目标。
首先,您有一个应用程序在服务器上运行,包含核心,它封装了模块 。您从这里开始的较低级别可以包含更多模块或控制器。我将解决这两个问题。
先决条件包括但不限:
如果您需要控制器之间的通信网络,请使用标准Angular $scope
& 模块中的$rootScope
.$broadcast
,.$emit
和.$on
实用程序 - 您可能已经想到了这一点;)
要在模块之间进行通信,请在核心中实现中介模式 - 可能,这将作为每个模块可以引入的服务实现;否则,您的模块可以初始化&提供了一个注入了 Mediator / Director 的沙箱。现在, application-core 中的 modules 可以进行通信。
说,您需要此应用程序 / 核心与另一个应用程序进行通信。使用自定义事件实现 SharedWorker。您可以看到一个框架"worker.io" I built for UCLA here。该项目可以使用一些修饰,所以随意使用它作为编写自己的参考 - 关注点是它使用 Pseudo Port-Entanglement 。这是因为工作人员只允许onmessage
处理程序,因此您要创建new MessageEvent
;将它作为JSON字符串发送到另一个端口,然后发送JSON.parse`消息以获取自定义事件并在接收事件的端口上调度该事件 - 这为您提供了自定义事件。现在,任何应用程序都可以利用此 SharedWorker 并通过它与其他应用程序通信 - 它甚至允许在浏览器选项卡之间进行 。
如果您想要一种更全面的事件驱动架构方法,比如说,为服务器上的模块提供响应事件的机会(来自任何地方) - - 在您的服务器上实现 event-hub 。这可能比你想要开展的项目更多,但是存在一本很好的书,描述了如何设置它:Testable JavaScript, Mark Ethan Trostler。
也就是说,完全可以使用 Mediators , SharedWorkers 和 EventHubs 在后端。
上面提到的 worker.io 框架使用了两个库: Apis (拉丁语中的Bee)和 Scriptorium (拉丁语中的Hive)。但是,要了解如何实现库,请参阅js directory。
希望这有帮助。
答案 1 :(得分:5)
我只是想知道如何正确地做到这一点。
“正确”是非常主观的。 “正确”是任何有效的,易于理解和可维护的。
那就是说,为什么不使用$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也会有效。
答案 2 :(得分:-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;
});
};
});