javascript - Angularjs event communication between directives with publishsubscribe - Stack Overflow

I want to create a publishsubscribe mechanism with angular event system. angular.module("app"

I want to create a publish/subscribe mechanism with 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);
            });
      }
    }
})

if I set HTML document like this, no message appear in console:

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

If I change order first and second, message wirite on console.

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

But I need first directive or inner directive.

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

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

I tried both $rootScope.$broadcast and $rootScope.$emit but did not woeked.

Working DEMO

I want to create a publish/subscribe mechanism with 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);
            });
      }
    }
})

if I set HTML document like this, no message appear in console:

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

If I change order first and second, message wirite on console.

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

But I need first directive or inner directive.

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

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

I tried both $rootScope.$broadcast and $rootScope.$emit but did not woeked.

Working DEMO

Share Improve this question asked May 5, 2016 at 8:40 bartelomabarteloma 6,88516 gold badges94 silver badges209 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

It's absolutely correct angular behavior.

In the first example:

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

Angular creates a directive for first tag and sends event immediately, but the second directive is not created yet.

In the second example:

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

Here you firstly subscribe to an event, and after that first directive sends a message. Because of this, second directive accepts an event.

Third example:

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

This case, as well as the first example won't be working.

Solution: One of solutions is to set timeout in first directive to don't send event immediately after creation. If the second parameter of $timeout, delay is not provided, the default behaviour is to execute the function after the DOM has pleted rendering:

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

Demo

This happens because when broadcast of first directive is executed, the second directive is not ready and therefore the signal is lost and munication does not happen. One way of solving it, is to send the signal many times using $interval function and stop transmitting only when the second directive is ready. Of course the second directive has to broadcast back when it receives data from the first. The second solution, for which I would go, is for the second directive to notify when its ready to the first directive by broadcasting with $rootScope in a similar fashion as you did in first directive.

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

and the first directive:

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

Since you are using a parent child structure, it is always guaranteed that the first directive will be ready when child directives are ready. Using this solution you could use many child directives. Hope this helps!

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744630031a4584803.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信