13

Im trying to send a message from within a directive to its parent controller (without success)

Here is my HTML

<div ng-controller="Ctrl">
   <my-elem/>
</div>

Here is the code in the controller which listens for the event

$scope.on('go', function(){ .... }) ;

And finally the directive looks like

angular.module('App').directive('myElem',
   function () {
    return {
        restrict: 'E',
        templateUrl: '/views/my-elem.html',
        link: function ($scope, $element, $attrs) {
            $element.on('click', function() {
                  console.log("We're in") ; 
                  $scope.$emit('go', { nr: 10 }) ;
            }
        }
    }
  }) ;

I've tried different scope configuration and $broadcast instead of $emit. I see that the event gets fired, but the controller does not receive a 'go' event. Any suggestions ?

2

3 Answers 3

26

There is no method on with scope. In angular it's $on

below should work for you

<!doctype html>
<html ng-app="test">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.js"></script>

  </head>
 <body ng-controller="test" >    
 <my-elem/>

<!-- tabs -->


 <script>
     var app = angular.module('test', []);
     app.controller('test', function ($scope) {

         $scope.$on('go', function () { alert('event is clicked') });
     });
     app.directive('myElem',
   function () {
       return {
           restrict: 'E',
           replace:true,
           template: '<div><input type="button" value=check/></input>',
           link: function ($scope, $element, $attrs) {
               alert("123");
               $element.bind('click', function () {
                   console.log("We're in");
                   $scope.$emit('go');
               });
               }
       }
   }) ;

   </script>
</body>


</html>
Sign up to request clarification or add additional context in comments.

1 Comment

The closing tag </input> is bad HTML.
2
+50

To get { nr: 10 } you should add 2 arguments to listener: event and data:

$scope.$on('go', function(event, data){ 
  alert(JSON.stringify(data));
});

(keep in mind that we use $on and not on)

Full example in plunker

Comments

1

$broadcast, $emit, and $on are deprecated

Use of the scope/rootScope event bus is deprecated and will make migration to Angular 2+ more difficult.

To facilitate making the transition to Angular 2+ easier, AngularJS 1.5 introduced components:

app.component("myElem", {
    bindings: {
      onGo: '&',
    },
    template: `
        <button ng-click="$ctrl.go($event,{nr:10})">
            Click to GO
        </button>
    `,
    controller: function() {
        this.go = (event,data) => {
            this.onGo({$event: event, $data: data});
        };
    }
});

Usage:

<div ng-controller="Ctrl as $ctrl">
   <my-elem on-go="$ctrl.fn($data)></my-elem>
</div>

The component uses an attribute with AngularJS expression (&) binding that invokes a function in the parent controller. Instead of clogging the scope/rootScope event bus with numerous events, the event goes directly to the function that uses it.

The DEMO

angular.module('app', [])
.controller ('Ctrl', function () {
    this.go = (data) => {
      console.log(data);
      this.update = data;
    };
})
.component("myElem", {
    bindings: {
      onGo: '&',
    },
    template: `
      <fieldset>
        <input ng-model="$ctrl.nr" /><br>
        <button ng-click="$ctrl.go($event,$ctrl.nr)">
            Click to Update
        </button>
      </fieldset>
    `,
    controller: function() {
        this.nr = 10;
        this.go = (event,data) => {
            this.onGo({$event: event, $data: data});
        };
    }
})
<script  src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="Ctrl as $ctrl">
    <p>update={{$ctrl.update}}</p>
    <my-elem on-go="$ctrl.go($data)"></my-elem>
</body>

For more information, see

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.