DrewB
DrewB

Reputation: 1536

Can't pass function to directive

I have a controller and directive defined as:

angular.module('cms', ['TestMod'])
.controller('MainCtrl', function() {
  this.refreshPage = function() {
    alert('Hello World');
  };
});

angular.module('TestMod', [])
.directive('testCtl', function() {
  return {
    scope: {
      tmOnClose: '&',
    },
    template: '<div ng-click="close()">Hello World</div>',
    link: function(scope, element, attrs) {
      scope.close = function() {
        if(scope.tmOnClose)
            scope.tmOnClose();
      }
    }
  }
 })

In my HTML, I'm attempting to pass the refreshPage function into the directive like:

<html ng-app="cms">

    <head>
        <script data-require="[email protected]" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js"></script>
    </head>

    <body ng-controller="MainCtrl">
        <h1>Hello Plunker!</h1>
        <test-ctl tm-on-close="refreshPage"></test-ctl>
    </body>
</html>

When I click the directive, the close function is called, but the refreshPage function is never called. Upon debugging, the value of scope.tmOnClose() is always

function(b)(return n(a,b))

How do I get the actual function so that I can call it from within the directive?

Plunker Here

Edit: I have to tell on myself. I set this sample up from a much larger project because I didn't want to paste pages of code in here when it wasn't clear what was relevant. Sergio's answer is 100% correct and was actually a problem I had. However, my larger problem was that in my larger app, my was not contained within the that defined my controller. I add this in as a note to hopefully help someone else because apparently angularjs, in a case like this, won't tell you that something is undefined, it'll just define it and pass it in.

Upvotes: 0

Views: 692

Answers (3)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230521

First, give a name to your controller. Second, invoke the function when using in the directive with & isolate scope.

<body ng-controller="MainCtrl as ctrl">
    <h1>Hello Plunker!</h1>
    <test-ctl tm-on-close="ctrl.refreshPage()"></test-ctl>
</body>

Upvotes: 2

kiranml1
kiranml1

Reputation: 44

function can be passed to a directive with '=' in scope object

angular.module('cms', ['TestMod'])
 .controller('MainCtrl', function() {
      this.refreshPage = function() {
      alert('Hello World');
  };
 });

angular.module('TestMod', [])
 .directive('testCtl', function() {
     return {
       scope: {
         tmOnClose: '=',
       },
       template: '<div ng-click="close()">Hello World</div>',
       link: function(scope, element, attrs) {
              scope.close = function() {
              if(scope.tmOnClose)
                scope.tmOnClose();
          }
        }
       }
  })

"controller as" syntax must be used since controller scope is declared with refreshPage function

<!DOCTYPE html>
<html ng-app="cms">

  <head>
    <script data-require="[email protected]" data-semver="1.4.6"   src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainCtrl as ctrl">
    <h1>Hello Plunker!</h1>
    <test-ctl tm-on-close="ctrl.refreshPage"></test-ctl>
  </body>

</html>

Upvotes: -1

Mathew Berg
Mathew Berg

Reputation: 28750

When using & you have to reference it like this:

<test-ctl tm-on-close="refreshPage()"></test-ctl>

Upvotes: 0

Related Questions