Airerr
Airerr

Reputation: 479

AngularJS Passing function with arguments to event directive

To start off, I know there are loads of similar questions but none that I found which supports execution of arbitrary methods with event listeners.

I have this directive which executes functions passed when the window resizes.

app.directive('onResize', function() {
  var directive = {
    'link': function(scope, element, attrs) {
      var onResizeHandler = scope.$eval(attrs.onResize);
      angular.element(window).on('resize', onResizeHandler);
      angular.element(window).on('$destory', function() {element.off();});
    }
  };
  return directive;
});

I can trigger the above directive with

<div data-on-resize="stickyHeader">...</div>

Which runs my method, inside my controller.

app.controller('myController', [$scope, function($scope) {
  $scope.stickyHeader = function() {
    console.log('event triggered') 
  };
}]);

All the above code works fine, but I need to pass some arguments to stickyHeader as in data-on-resize="stickyHeader(arg1, arg2)" When I try that, I get Cannot read property 'call' of undefined at ng (angular.js:3795) in the console. Not sure what I can do to make my directive support arbitrary methods with arguments.

Upvotes: 1

Views: 1779

Answers (1)

georgeawg
georgeawg

Reputation: 48968

The directive needs to evaluate the AngularJS expression defined by the on-resize attribute every time the events occurs:

app.directive('onResize', function($window) {
  var directive = {
    link: function(scope, elem, attrs) {
      angular.element($window).on('resize', onResizeHandler);
      scope.$on('$destroy', function() {
         angular.element($window).off('resize', onResizeHandler);
      });
      function onResizeHandler(event) {
         scope.$eval(attrs.onResize, {$event: event});
         scope.$apply();
      }
    }
  };
  return directive;
});

Also since the resize event comes from outside the AngularJS framework, the event needs to be brought into the AngularJS execution context with $apply().

Further, to avoid memory leaks, the event handler needs to be unbound when the scope is destroyed.

Usage:

<div data-on-resize="stickyHeader($event)">...</div>

For more information, see AngularJS Developer Guide - $event.

Upvotes: 3

Related Questions