简体   繁体   English

angularjs $ rootscope事件不会在父指令上触发

[英]angularjs $rootscope event does not fire on parent directive

I have two directive on my design. 我的设计有两个指令。

var app = angular.module("app",[]);

app.directive("dirContainer", function($rootScope){
      return {
       template: "<div><clock></clock></div>",
       link:function(scope){        
        $rootScope.$on("onClockCreated",function(){
                alert(1)
        })
      }
    }
});

app.directive("clock", function($rootScope){
      return {
       template: "<div>clock</div>",
       link:function(scope){
            var clock = { time: "10:12" };

          $rootScope.$broadcast("onClockCreated",clock);
      }
    }
});

I want to get clock directive created event with $rootScope broadcast. 我想获取带有$rootScope广播的clock指令创建的事件。 But container directive does not populate the alert. 但是容器指令不会填充警报。

This is DEMO of application. 这是应用程序的演示

UPDATE: 更新:

I have added scope.$emit and it populated alert. 我添加了scope。$ emit并填充了警报。

app.directive("dirContainer", function($rootScope){
        return {
        template: "<div><clock></clock></div>",
      compile:function(scope){          
        $rootScope.$on("onClockCreated",function(){
                alert(1)
        })

        $scope.$emit("onClockCreated",function(){
                alert(1)
        })
      }
    }
});

But I could not understand. 但是我听不懂。 How it wroks? 它如何运作?

You have got a timing problem here. 您在这里遇到时间问题。 The link function of the clock directive is called before the link function of your dirContainer directive. 在dirContainer指令的链接功能之前调用clock指令的链接功能。 You can see it, if you put a console.log in each link function. 如果将console.log放在每个链接函数中,则可以看到它。 So your event is emitted before the dirContainer directive is listening. 因此,您的事件是在dirContainer指令正在侦听之前发出的。 If you could tell us what you are trying to achieve, we maybe could suggest you an appropriate solution. 如果您可以告诉我们您要达到的目标,我们可能会建议您一个适当的解决方案。

Just change link to compile 只需更改link即可compile

compile:function(scope){        
            $rootScope.$on("onClockCreated",function(){
                    alert(1)
            })
          }

here is demo https://jsfiddle.net/avsubL66/ 这是演示https://jsfiddle.net/avsubL66/

You can even do this in way by creating parent child directive manner 您甚至可以通过创建父子指令方式来实现此目的

 <div ng-app="myapp">
<container>
  <clock></clock>
  </container>
   </div>
var app = angular.module("myapp",[]);


app.directive("container", function () {
  return {
    restrict: "E",
    controller: function () {
      this.clockcreated = function (message) { 
        alert("It says: " + message);
      };
    }
  };
});


app.directive("clock", function () {
  return {
    restrict: "E",
    require: "^container",
    link: function (scope, element, attrs, containerCtrl) {
      containerCtrl.clockcreated("Clock created");
    }
  };
});

Working link - https://jsfiddle.net/2nqhsvmp/1/ 工作链接-https://jsfiddle.net/2nqhsvmp/1/

One way to solve this problem is to expose an api for your parent controller. 解决此问题的一种方法是为您的父控制器公开一个api。

Working fork of your fiddle . 你的小提琴的工作叉。

This resolves your concerns with race conditions. 这样可以解决您对比赛条件的担忧。

var app = angular.module("app",[]);

app.directive("dirContainer", function($rootScope){
    return {
    template: "<div><clock></clock></div>",
    controller: ['$scope', function DirContainerController($scope) {
        this.sendAlert = function() {
            alert(1);
        };
    }],
    }
});

app.directive("clock", function($timeout, $rootScope){
    return {
    require: '^^dirContainer',
    template: "<div>clock</div>",
    link:function(scope, element, attrs, dirCtrl){
        var clock = { time: "10:12" };
            dirCtrl.sendAlert();
        }
    }
});

Here is the solution, 这是解决方案,

your dirContrainer directive should listen to the broadcast on his scope . 您的dirContrainer指令应在其scope上收听广播。 Not his rootScope . 不是他的rootScope

app.directive("dirContainer", function($rootScope){
        return {
        template: "<div><clock></clock></div>",
      link:function(scope){         
        scope.$on("onClockCreated",function(clock){
                alert(1)
        })
      }
    }
});

And also make sure to put a $timeout when you are doing this testing because broadcast.$on is not ready when you $broadcast from the clock directive. 并且还要确保在执行此测试时放置$timeout ,因为当您从clock指令进行$broadcast时, broadcast.$on尚未准备好。

app.directive("clock", function($rootScope, $timeout){
        return {
        template: "<div>clock</div>",
      link:function(scope){
            var clock = { time: "10:12" };

          $timeout(function () {
            $rootScope.$broadcast("onClockCreated",clock);
          });

      }
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM