[英]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.