monkeyWithAMachinegun
monkeyWithAMachinegun

Reputation: 331

AngularJS directive can't find required controller

The gist of this is that, in the code below, I need 'modalDirective' to access the list of elements to create, which lives inside 'modalController'. I also need 'modalDirective' to create an HTML element that uses ng-model to bind to a scoped variable inside 'modalController', so if there is another way to do either of these things I'm totally open to it.

I open a modal using the following parameters:

var modalOptions = {
    templateUrl: 'targetUrl/modalPage.html',
    controller: 'modalController'
}
ModalDialogFactory.openModal(modalOptions);

ModalDialogFactory really just opens the modal:

angular.module('myApp')
.factory('ModalDialogFactory', ['$modal', '$rootScope', function ($modal, $rootScope) {
    var modalDialogDefaults = {
        backdrop: 'static',
        keyboard: false,
        scope: $rootScope.$new()
    };
    var modalInstance;
    return {
        showModal: function (modalOptions) {
            var modalConfig = {};
            angular.extend(modalConfig, modalDialogDefaults, modalOptions);
            modalInstance = $modal.open(modalConfig);
            return modalInstance.result;
        },
        closeModal: function (selectedObjs) {
            if (modalInstance != null) {
                modalInstance.close(selectedObjs);
            }
        }
    };

}]);

The modal opens, and the controller works fine. So far so good. Now, in the target page I want to use a directive:

angular.module('myApp').directive('modalDirective', function ($q, $http, $compile) {
return {
    restrict: 'EAC',
    compile: function(element, attr) {
              return function(scope, element, attr) {
              // Dynamically create new HTML elements   
    }
};
});

And then in modalPage.html, I reference the modal directive:

<div modal-directive></div>

This works too, the directive creates the dynamic HTML elements as expected. The problem crops up when I want to bind one of those elements to a scoped variable inside 'modalController'. The directive doesn't seem to have access to the controller, which I figured to be some kind of scoping issue but I'm not sure where I'm going wrong. I tried adding this line to the 'modalDirective':

require: '^^modalController',

But when I try and require the controller I get an error:

Error: [$compile:ctreq] Controller 'modalController', required by directive 'modalDirective', can't be found!

Does anyone know where I'm going wrong?

Upvotes: 0

Views: 177

Answers (1)

kendavidson
kendavidson

Reputation: 1460

(Assumption, using uibModal, or another $modal that allows for resolve)

I know this is late to the party, but came across this while browsing through some older tasks. The issue with your require is that the $modal service adds the modal entry to the HTML outside of the scope of the controller (unless the controller is the full page, which seems unlikely).

Instead of expecting the scope to be passed, you'll probably want to take advantage of the resolve attribute of $modal configuration. So you'd do something like:

  • Create the modal options passing in the properties to the resolve attribute
  • Do your modal stuff
  • Return any updates through the $modalInstance.close() which you're already doing

It'll end up something like:

ModalDialogFactory.showModal({
    resolve: {
        listOfStuff: function() { return $scope.list; }
    }
});

Which will give you scope.listOfStuff available to work with in your directive.

Upvotes: 1

Related Questions