How to access controller functions in directive link?

11,588

Publishing on the scope can work, but not the best practice, since it "pollutes" the scope. The proper way to communicate with own controller is to require it - then it will become available as a parameter to the link function, along with other required directives.

The other issue is with how you expose functions on the controller - this is done by using this.someFn, not by returning an object.

app.directive('showLoading', function() {
  return {
    restrict: 'A',
    require: ['ngModel', 'showLoading'], // multiple "requires" for illustration
    scope: {
      loading: '=showLoading'
    },
    controller: function($scope, $element) {
      this.show = function() {
        alert("show");
      };

      this.hide = function() {
        alert("hide");
      };
    },
    link: function($scope, $element, $attrs, ctrls) {
      var ngModel = ctrls[0], me = ctrls[1];

      $scope.$watch('loading', function(bool) {
        if (bool) {
          me.show();
        } else {
          me.hide();
        }
      });
    }
  };
});
Share:
11,588
luzny
Author by

luzny

Updated on July 22, 2022

Comments

  • luzny
    luzny almost 2 years

    How to access directive controller functions from directive link? Bellow controller passed to link is empty, I would like to get in it show() hide() functions.

    My current directive:

    app.directive('showLoading', function() {
      return {
        restrict: 'A',
        // require: 'ngModel',
        scope: {
          loading: '=showLoading'
        },
        controller: function($scope, $element) {
          return {
            show: function() {
              alert("show");
            },
            hide: function() {
              alert("hide");
            }
          };
        },
        link: function($scope, $element, $attrs, controller) {
          $scope.$watch('loading', function(bool) {
            if (bool) {
              controller.show();//undefined
            } else {
              controller.hide();
            }
          });
        }
      };
    });