madhead
madhead

Reputation: 33491

Angular UI Modal controller is not exposed to directives

I need to create a directive that can be used inside Angular UI modal. This directive also need to know about modal's controller in order to use some functions from it. What I have now:

JS:

'use strict';

var DemoApp = angular.module('DemoApp', [ 'ui.bootstrap' ]);

DemoApp.controller('PageController', ['$scope', '$modal', function($scope, $modal){
  $scope.openModal = function(){
    var scope = $scope.$new(true);

    $modal.open({
      'templateUrl' : 'modal.html',
      'controller' : 'ModalController',
      'scope' : scope
    });
  }
}]);

DemoApp.controller('ModalController', ['$scope', '$modalInstance', function($scope, $modalInstance){
  $scope.ok = function() {
    $modalInstance.dismiss();
  };

  $scope.cancel = function() {
    $modalInstance.dismiss();
  };
}]);

DemoApp.directive('expression', function() {
  return {
    restrict : 'A',
    require : ['ngModel', '^ModalController'],
    link : function(scope, element, attrs, controllers) {
      console.log(arguments);
    }
  };
});

Modal template:

<div class="modal-header">
  <h3>Test!</h3>
</div>
<div class="modal-body">
  <input data-ng-model="someValue" expression>{{someValue}}
</div>
<div class="modal-footer">
  <button class="btn btn-primary" data-ng-click="ok()">Ok</button>
  <button class="btn btn-warning" data-ng-click="cancel()">Cancel</button>
</div>

And the red button:

<button id="demoButton" class="btn btn-primary" data-ng-click="openModal()">Click me!</button>

But when the modal is created ModalController is not resolved, and I get $compile:ctreq error:

Error: [$compile:ctreq] http://errors.angularjs.org/1.2.17/$compile/ctreq?p0=ModalController&p1=expression
    at Error (native)
    at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:6:450
    at D (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:51:80)
    at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:51:137
    at Array.forEach (native)
    at q (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:7:280)
    at D (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:51:114)
    at N (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:54:128)
    at g (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:47:82)
    at g (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js:47:99) <input data-ng-model="someValue" expression="" class="ng-pristine ng-valid">

I tried to debug the code: getControllers() somewhere around 6433 LOC at angular.js is used to search controller: value = value || $element[retrievalMethod]('$' + require + 'Controller');, so I tried to require Modal instead of ModalController (Controller is appended by Angular), but it didn't help. I cannot understand how $element[retrievalMethod] works (stepped into it, but it is to low-level). So, I'm stuck and appreciate any help.

I've created a Plunk, so you can play and see in console what I mean.

Upvotes: 3

Views: 722

Answers (1)

dubadub
dubadub

Reputation: 3342

Please, checkout updated plunker:

  1. ModalController scope isn't child scope of PageController, so if you need to pass variables to ModalController you should do it through resolving dependencies directly.

  2. In your directive you can set scope as child of ModalController scope, so you can have access to functions defined there instead of requiring ModalController.

Upvotes: 3

Related Questions