两个 angularjs 服务之间的消息传递
Messaging between two angularjs services
我想在 angularjs 网站中实现两个服务之间的通信(通过发送和接收消息)。实际上,如果我们可以将两个服务合并为一个服务,则消息传递将是不必要的。但现实是出于某种原因我不想合并它们。由于两个服务不可能相互依赖(如果我错了请指正),看来我必须让他们通过消息进行通信。
让我解释一下...假设我们有两个服务 serA
和 serB
。在 serA
中,我们有
this.startTask1 = function () {
console.log("B, please do task 1")
sendMsgFromAtoB("B, please do task 1")
}
this.receiveMsgFromBtoA = function (msg) {
if (msg === "A, B has done task 1") {
console.log("A, B has done task 1");
console.log("task 1 is finally over!!!")
}
}
在serB
中,我们有
this.receiveMsgFromAtoB = function (msg) {
if (msg === "B, please do task 1") {
console.log("B is doing task 1... Done!");
sendMsgFromBtoA("A, B has done task 1")
}
}
因此,如果控制器运行 serA.startTask1()
,我希望在控制台中看到:
B, please do task 1
B is doing task 1... Done!
A, B has done task 1
task 1 is finally over!!!
为此,我需要制作sendMsgFromAtoB
和sendMsgFromBtoA
,完成receiveMsgFromAtoB
和receiveMsgFromBtoA
。但是,我不知道我可以通过什么方式实现它们。
我用过$window.addEventListener("message", ...)
(即postMessage
)和$window.addEventListener("storage", ...)
(即StorageEvent
)。但是 StorageEvent
不是完全跨平台的,我不确定 postMessage
是否适合在一页内发送消息。
那么大家有什么好主意吗?
您已经在 Angular 1.x 应用中获得了事件总线,$rootScope
。除非你愿意在项目中引入第三方库(RxJS、EventEmitter3 或其他 pub/sub 实现),否则没有理由再看下去了。
$rootScope.$on('foo', (e, arg1, arg2) => { ... });
...
$rootScope.$emit('foo', arg1, arg2);
循环依赖总是mixing of concerns, which is a really bad thing. Miško Hevery, one of the authors of AngularJS, explains a nice solution on his awesome blog的标志。简而言之,您可能在某个地方隐藏了第三个服务,这是其他两个真正需要的代码的唯一部分。
变化:
+---------+ +---------+
| A |<-----| B |
| | | | +-+ |
| | | +->|C| |
| |------+---->| | |
| | | +-+ |
+---------+ +---------+
为此:
+---------+
+---------+ | B |
| A |<-------------| |
| | | |
| | +---+ | |
| |--->| C |<----| |
| | +---+ +---------+
+---------+
另见,
- Problems with circular dependency and OOP in AngularJS
- Miško Hevery, Circular Dependency in constructors and Dependency Injection
我想在 angularjs 网站中实现两个服务之间的通信(通过发送和接收消息)。实际上,如果我们可以将两个服务合并为一个服务,则消息传递将是不必要的。但现实是出于某种原因我不想合并它们。由于两个服务不可能相互依赖(如果我错了请指正),看来我必须让他们通过消息进行通信。
让我解释一下...假设我们有两个服务 serA
和 serB
。在 serA
中,我们有
this.startTask1 = function () {
console.log("B, please do task 1")
sendMsgFromAtoB("B, please do task 1")
}
this.receiveMsgFromBtoA = function (msg) {
if (msg === "A, B has done task 1") {
console.log("A, B has done task 1");
console.log("task 1 is finally over!!!")
}
}
在serB
中,我们有
this.receiveMsgFromAtoB = function (msg) {
if (msg === "B, please do task 1") {
console.log("B is doing task 1... Done!");
sendMsgFromBtoA("A, B has done task 1")
}
}
因此,如果控制器运行 serA.startTask1()
,我希望在控制台中看到:
B, please do task 1
B is doing task 1... Done!
A, B has done task 1
task 1 is finally over!!!
为此,我需要制作sendMsgFromAtoB
和sendMsgFromBtoA
,完成receiveMsgFromAtoB
和receiveMsgFromBtoA
。但是,我不知道我可以通过什么方式实现它们。
我用过$window.addEventListener("message", ...)
(即postMessage
)和$window.addEventListener("storage", ...)
(即StorageEvent
)。但是 StorageEvent
不是完全跨平台的,我不确定 postMessage
是否适合在一页内发送消息。
那么大家有什么好主意吗?
您已经在 Angular 1.x 应用中获得了事件总线,$rootScope
。除非你愿意在项目中引入第三方库(RxJS、EventEmitter3 或其他 pub/sub 实现),否则没有理由再看下去了。
$rootScope.$on('foo', (e, arg1, arg2) => { ... });
...
$rootScope.$emit('foo', arg1, arg2);
循环依赖总是mixing of concerns, which is a really bad thing. Miško Hevery, one of the authors of AngularJS, explains a nice solution on his awesome blog的标志。简而言之,您可能在某个地方隐藏了第三个服务,这是其他两个真正需要的代码的唯一部分。
变化:
+---------+ +---------+
| A |<-----| B |
| | | | +-+ |
| | | +->|C| |
| |------+---->| | |
| | | +-+ |
+---------+ +---------+
为此:
+---------+
+---------+ | B |
| A |<-------------| |
| | | |
| | +---+ | |
| |--->| C |<----| |
| | +---+ +---------+
+---------+
另见,
- Problems with circular dependency and OOP in AngularJS
- Miško Hevery, Circular Dependency in constructors and Dependency Injection