[英]Angularjs event communication between directives with publish/subscribe
我想用角度事件系统创建一个发布/订阅机制。
angular.module("app",[]);
angular.module("app").directive("first", function($rootScope){
return {
template: "First Directive",
link:function(scope,element,attribute){
$rootScope.$broadcast("OnFirstDirectiveCreated", {
"message": "I'm first directive"
});
}
}
})
angular.module("app").directive("second", function($rootScope){
return {
template: "Second Directive",
link:function(scope,element,attribute){
var handler = $rootScope.$on("OnFirstDirectiveCreated",
function (event, args) {
console.log("First Directive Message: " + args.message);
});
}
}
})
如果我这样设置HTML文档,则控制台中不会显示任何消息:
<div ng-app="app">
<first></first>
<second></second>
</div>
如果我先更改顺序,然后在控制台上写消息。
<div ng-app="app">
<second></second>
<first></first>
</div>
但是我需要第一个指令或内部指令。
<div ng-app="app">
<first></first>
<second></second>
</div>
<div ng-app="app">
<first>
<second></second>
</first>
</div>
我尝试了$rootScope.$broadcast
和$rootScope.$emit
但是都没问题。
这是绝对正确的角度行为。
在第一个示例中:
<first></first>
<second></second>
Angular为first
标记创建一个指令并立即发送事件,但尚未创建第二个指令。
在第二个示例中:
<first></first>
<second></second>
在这里,您首先订阅一个事件,然后该first
指令发送一条消息。 因此, second
指令接受一个事件。
第三个例子:
<first>
<second></second>
</first>
这种情况以及第一个示例都行不通。
解决方案:解决方案之一是在第一个指令中设置超时,以使其在创建后不立即发送事件。 如果不提供$timeout
的第二个参数delay
,则默认行为是在DOM完成渲染后执行该函数:
angular.module("app").directive("first", function($rootScope, $timeout) {
return {
template: "First Directive",
link: function(scope,element,attribute) {
$timeout(function() {
$rootScope.$broadcast("OnFirstDirectiveCreated", {
"message": "I'm first directive"
})
});
}
}
});
发生这种情况的原因是,当执行第一个指令的广播时,第二个指令未准备好,因此信号丢失并且通信没有发生。 解决它的一种方法是使用$ interval函数多次发送信号,并仅在第二条指令就绪时才停止发送信号。 当然,第二个指令从第一个指令接收数据时必须广播回去。 我要讲的第二种解决方案是,第二条指令通过以与您在第一条指令中类似的方式与$ rootScope进行广播,以通知第二条指令何时准备好接收第一条指令。
angular.module("app").directive("second", function($rootScope){
return {
template: "Second Directive",
link:function(scope,element,attribute){
var handler = $rootScope.$on("secondDirective",
function (event, args) {
console.log("First Directive Data: " + args);
});
$rootScope.$broadcast("OnChildDirectiveCreated", {
"message": "I'm second directive",
"id": "secondDirective"
});
}
}
})
和第一个指令:
angular.module("app").directive("first", function($rootScope){
return {
template: "First Directive",
link:function(scope,element,attribute){
$rootScope.$on("OnChildDirectiveCreated", function(event, args) {
$rootScope.$broadcast(args.id, someData);
});
}
}
})
由于您使用的是父子结构,因此始终可以确保当子指令就绪时,第一个指令也将就绪。 使用此解决方案,您可以使用许多子指令。 希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.