Javascript 指令与发布/订阅之间的Angularjs事件通信

Javascript 指令与发布/订阅之间的Angularjs事件通信,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我想用angular event system创建一个发布/订阅机制 angular.module("app",[]); angular.module("app").directive("first", function($rootScope){ return { template: "First Directive", link:function(scope,element,attribute){ $roo

我想用angular event system创建一个发布/订阅机制

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>

若我第一次和第二次更改顺序,控制台上会显示消息wirite

<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>
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"
        });
      }
    }
 })

我尝试了
$rootScope.$broadcast
$rootScope.$emit
,但没有失败


这是绝对正确的角度行为

在第一个示例中:

<first></first>
<second></second>
在这里,您首先订阅一个事件,然后
first
指令发送一条消息。因此,
second
指令接受一个事件

第三个例子:

<first></first>
<second></second>
<first>
   <second></second>
</first>

发生这种情况的原因是,当执行第一个指令的广播时,第二个指令未准备就绪,因此信号丢失,无法进行通信。解决此问题的一种方法是使用$interval函数多次发送信号,并仅在第二个指令就绪时停止发送。当然,当第二个指令从第一个指令接收数据时,它必须广播回来。 第二种解决方案(我将对此进行说明)是,第二条指令在准备好发送到第一条指令时,通过使用$rootScope以与第一条指令中类似的方式进行广播来通知第二条指令

<div ng-app="app">
  <first></first>
  <second></second>
</div>

<div ng-app="app">
  <first>
      <second></second>
  </first>
</div>
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);
           });
      }
   }
})

由于您使用的是父子结构,因此始终保证在子指令就绪时第一个指令将就绪。使用此解决方案可以使用许多子指令。希望这有帮助

$timeout 0秒让我有点困惑。如果我的第二个指令加载几秒钟,可能会有问题吗?我们无法知道其他指令的加载时间。我已经更新了一个答案,如果您将使用
$timeout
而不使用
delay
参数,则该函数将在DOM完成渲染后执行。