Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
367 views
in Technique[技术] by (71.8m points)

javascript - AngularJS - $emit only works within it's current scope?

I've created 2 directives: Parent and Child. Trying to get them to talk to one another. It seems if they both have a scope they don't receive the events. This doesn't seem correct according to the documentation which $emit states: Dispatches an event name upwards through the scope hierarchy notifying the registered ng.$rootScope.Scope#methods_$on listeners.

So surely that should bubble up through scopes?

http://plnkr.co/edit/WNqN4XZKaLAvBEtSyERA?p=preview

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is with you parent/child assumption:

  • Parent is only a parent element of Child but not a parent scope.
  • Actually they are sibling scopes, both children of the $rootScope ($id: 002) in this case.

Why??

  • Due to this commit, Isolate scope is now available only to the isolate directive that requested it and its template.
  • It means that parent directive contents (which included the child directive) are still linked to the outer scope.
  • So the child directive creates isolated scope which is a child of the outer scope.
  • Neither $emit nor $broadcast would work with sibling scopes.

enter image description here


Solution:

here is a plunker: http://plnkr.co/edit/EfKJthkQLitWnF2srykM?p=preview

You can create the child directive as a template of the parent directive, because template directives do get the directive's scope as mentioned above.

.directive('parent', function ($timeout) {
  return {
    template:'<child name="Jimmy"></child>',

do you really need the event bus?

Another solution would be to create a controller on the parent directive and to require it in child directives.

.directive('parent', function ($timeout) {
  return {
    controller: function(){
      this.hungry = function(message){
        // something
      }
    }

child directive:

.directive('child', function ($timeout) {
  return {
    require: "^parent",
    link: function (scope, element, attrs, parentCtrl) {

       parentCtrl.hungry("I'm hungry!")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...