1

I was just reading here about accessing one directive's controller from within another directive via the require option:

  http://jasonmore.net/angular-js-directives-difference-controller-link/

The directive droppable and dashboard declarations in on my view - on two different divs:

  <div class="wrapper wrapper-content animated fadeInRight">
<div class="row">        
    <div class="col-lg-12" data-droppable drop="handleDrop">
        <div id="dash" dashboard="dashboardOptions" class="dashboard-container"></div>
    </div>
</div>

However I can't seem to get it to work. My dashboardCtrl param below is NULL.

Here in my droppable directive, I use the REQUIRE option:

  .directive('droppable', function () {
return {
    scope: {
        drop: '&',
    },
    //****************** dashboard directive is optionally requested ************
    require: '?dashboard', 

    link: function (scope, element, attributes, dashboardCtrl) {
         el.addEventListener('drop', function (e) {

            if (e.preventDefault) { e.preventDefault(); }

            this.classList.remove('over');
            var item = document.getElementById(e.dataTransfer.getData('Text'));                
            this.appendChild(item.cloneNode(true));

            // *** CALL INTO THE dashboardCtrl controller ***
            dashboardCtrl.addWidgetInternal();


            return false;
        }, false);
    }
}
});

and the dashboard directive :

 angular.module('ui.dashboard')
.directive('dashboard', ['WidgetModel', 'WidgetDefCollection', '$modal', 'DashboardState', '$log', function (WidgetModel, WidgetDefCollection, $modal, DashboardState, $log) {
  return {
      restrict: 'A',
      templateUrl: function (element, attr) {
          return attr.templateUrl ? attr.templateUrl : 'app/shared/template/dashboard.html';
      },
      scope: true,      
      controller: ['$scope', '$attrs', function (scope, attrs) {
            // ommitted for brevity
        }],
      link: function (scope) {                
            scope.addWidgetInternal = function (event, widgetDef) {
              event.preventDefault();
              scope.addWidget(widgetDef);
          };
      };
   }
}]);

However, my dashboardCtrl parameter is NULL. Please help me to figure out how to use require.

I actually need to call the addWidget() function, which is within the link option; but I suppose I can copy or move that into the controller option.

thank you ! Bob

scniro
  • 16,844
  • 8
  • 62
  • 106
bob.mazzo
  • 5,183
  • 23
  • 80
  • 149

1 Answers1

1

Here is an example of "parent" directive dashboard requiring droppable, and communication between the two making use of require and passing dashboardCtrl

Here is a good article to see directive to directive communication

Fiddle example also built from your previous question

JSFiddle

app.directive('droppable', [function () {
    return {
        restrict: 'A',
        require: 'dashboard',
        link: function (scope, elem, attrs, dashboardCtrl) {

            dashboardCtrl.controllerSpecificFunction('hello from child directive!');

            scope.addWidgetInternal = function(message) {
                console.log(message);
            }
        }
    }
}]);

app.directive('dashboard', [function () {
    return {
        restrict: 'A',
        controller: function ($scope) {
            $scope.handleDrop = function(message) {
                $scope.addWidgetInternal(message)
            }

            this.controllerSpecificFunction = function(message) {
                console.log(message);
           }
        }
    }
}]);


Edit

Based on discussion, here is a solution for what I currently understand the problem to be

Parent directive dashboard optionally requires child directive droppable and there needs to be communication between the two

<div dashboard>
    <button id="dash" droppable ng-click="handleDrop($event)">Handle Drop</button>
</div>


app.directive('droppable', [function () {
    return {
        restrict: 'A',
        require: '^?dashboard',
        link: function (scope, elem, attrs, dashboardCtrl) {
            scope.handleDrop = function($event) {
                dashboardCtrl.addWidgetInternal($event);
            }
        }
    }
}]);

app.directive('dashboard', [function () {
    return {
        restrict: 'A',
        controller: function ($scope) {
            this.addWidgetInternal = function($event) {
                console.log($event);
           }
        }
    }
}]);

Updated JSFiddle

scniro
  • 16,844
  • 8
  • 62
  • 106
  • funny thing: if I change it from `require: '?dashboard'` to `require: 'dashboard',' I get an Angular undefined error. It appears that the 'dashboard' directive is not yet available at the time 'droppable' is compiled. At least it's my theory, considering that '?' means it's optionally requested. – bob.mazzo Jan 09 '15 at 17:15
  • are you getting that in the fiddle? `require: 'dashboard'` and `require: '?dashboard'` both seem to be fine. Could it be something else on your end? – scniro Jan 09 '15 at 17:17
  • using `'?dashboard'` works fine in your fiddle. Could it be because my two directives are loaded from separate js files ? I loaded the dashboard directive file first, but maybe I need to merge them. – bob.mazzo Jan 09 '15 at 18:07
  • 1
    I am unsure, but I would expect that is not the issue. Do you have the directive declarations on the same element e.g. ``? Did this answer help you get in the right direction? – scniro Jan 09 '15 at 19:03
  • I'm sorry, as I never really was able to solve this one. On the bright side your help on http://stackoverflow.com/questions/27848095/in-angularjs-how-to-trigger-a-scope-function-defined-inside-a-directive pushed me in the right direction. – bob.mazzo Jan 09 '15 at 23:20
  • @bob been a while, hey have you had any luck on this one? – scniro Apr 19 '15 at 12:14
  • actually I ended up going with a different solution, but I have a feeling your suggestion here will help in the future. thank you for that. And this one was the one that I almost ended up using - a great trick/hack that you showed me here: http://stackoverflow.com/questions/27848095/how-to-trigger-a-scope-function-defined-inside-a-directive – bob.mazzo Apr 21 '15 at 13:44