繁体   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