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

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

7 Comments

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.
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?
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.
I am unsure, but I would expect that is not the issue. Do you have the directive declarations on the same element e.g. <button id="dash" dashboard draggable></button>? Did this answer help you get in the right direction?
I'm sorry, as I never really was able to solve this one. On the bright side your help on stackoverflow.com/questions/27848095/… pushed me in the right direction.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.