0

I have created a directive.

angular.module('app')
  .directive('navtree', function (service) {

    return {
      restrict: 'A',
      scope: {},
      link: function (scope, el) {

        scope.loadNavtree = function(){
          service.data()
              .then(function (data) {
                 ///Do something
              });
        }

        scope.loadNavtree();

      }
    };
  });

from my controller I can access the method using

$scope.$parent.$$childHead.loadNavtree();

Though this is working, I feel that this is not the right approach. I want to understand what are the disadvantages of accessing function defined in directive from your controller like this.

I looked this link but I was not able to follow

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
   /// How to call takeTablet() available in directive from here?
});

    app.directive('focusin', function factory() {
      return {
        restrict: 'E',
        replace: true,
        template: '<div>A:{{internalControl}}</div>',
        scope: {
          control: '='
        },
        link      : function (scope, element, attrs) {

          scope.takeTablet = function() {
            alert('from directive');// 
          }
        }
      };
    });
Community
  • 1
  • 1
SharpCoder
  • 18,279
  • 43
  • 153
  • 249
  • you are approaching this the wrong way. A directive is meant as a self contained module, it should not be defining functions internally that are meant to be called externally. You *can* define functions externally and pass them as references for the directive to call, however. If you *really* need the external resource to call an internal function, you should use `$broadcast / $emit`. – Claies Jul 16 '15 at 14:04
  • in your case, you probably should be defining a controller for the directive, and have the internal controller for the directive handle calling your init function when the directive loads. – Claies Jul 16 '15 at 14:06
  • @Claies: my directive contains a treeview control & based on changes made by user, the controller needs to call a function available in directive to reload the data. – SharpCoder Jul 16 '15 at 16:28
  • the point of a directive is to decouple sections of the UI into modular components. this doesn't sound like you are decoupling anything at all. The correct approach would be to have the shared function be a service that the directive can inject through dependency injection, and either have a flag variable that triggers the directive to make the service call, or a `$broadcast` which the service listens for to trigger the call. – Claies Jul 16 '15 at 19:39

1 Answers1

0

this is not the correct approach because angular do not recommend to use its private variable to access to directive function so you need to get a good approach to do that here is an example to access the directive function from controller.

If you want to use isolated scopes you can pass a control object using bi-directional binding ('=') of a variable from the controller scope. In this way you can control also several instances of the same directive on a page.

plunkr

Controller/Directive:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.focusinControl = {
  };
});

app.directive('focusin', function factory() {
  return {
    restrict: 'E',
    replace: true,
    template: '<div>A:{{internalControl}}</div>',
    scope: {
      control: '='
    },
    link      : function (scope, element, attrs) {
      scope.internalControl = scope.control || {};
      scope.internalControl.takenTablets = 0;
      scope.internalControl.takeTablet = function() {
        scope.internalControl.takenTablets += 1;  
      }
    }
  };
});

HTML:

<button ng-click="focusinControl.takeTablet()">Call directive function</button>
<h4>In controller scope:</h4>
{{focusinControl}}
<h4>In directive scope:</h4>
<focusin control="focusinControl"></focusin>
<h4>Without control object:</h4>
<focusin></focusin>
ngLover
  • 4,439
  • 3
  • 20
  • 42
  • Thank you for your reply. I did looked into this link ( http://stackoverflow.com/questions/16881478/how-to-call-a-method-defined-in-an-angularjs-directive ) & since I was not able to follow, I posted a question here. I have updated my question to give more information – SharpCoder Jul 16 '15 at 13:52
  • so you need a different approach other than link – ngLover Jul 16 '15 at 13:56
  • I should be able to call takeTablet() defined in directive from controller. – SharpCoder Jul 16 '15 at 13:57