簡體   English   中英

帶有發布/訂閱的指令之間的Angularjs事件通信

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM