following angular.ui Modal example shows the modalInstance
calling a ModalIntanceCtrl
which is later created as a function:
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
I have a 2 questions/problems:
the docs recommend creating a controller in another way (due to minification issues) for example:
myApp.controller('GreetingCtrl', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
But if I create the controller like this, how could I Inject it into the modalInstance?
- The controller I call here isn't a Modal Instance controller but my global
loginCtrl
, is this a problem? should I subclass somehow the loginCtrl or call it from the ModalInstanceCtrl? and if so - how exactly?
I'll be glad for guidance and clarfication about this.
Thanks!
You question is not very clear, but if you declare controller using the module API, then you can provide the controller to the modal service as a string
myApp.controller('ModalInstanceCtrl', ['$scope', function($scope) { $scope.greeting = 'Hola!'; }]);
controller: 'ModalInstanceCtrl',
The same can be done for loginCtrl
if you want to use that in the modal service.
I have created this plunker for those of you like myself, who like to see an example. It shows how to create a modal without polluting the global namespace. Hopefully it is helpful.
Edited to include code example as per bummi's comment below
index.html
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"> </script>
<script src="app.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="appController">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<span>Message:{{message}}</span>
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn btn-default" ng-click="showModal()">Open me!</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>
</body>
</html>
app.js
angular.module('app', ['ui.bootstrap']).
service('DataService', ['$rootScope',
function($rootScope) {
this.data = {};
this.data.message = 'This is a message from a service';
this.data.items = ['item1', 'item2', 'item3'];
}
]).
controller('myModal', ['$scope', '$modalInstance', 'DataService',
function($scope, $modalInstance, dataService) {
$scope.data = dataService.data;
$scope.message = dataService.data.message;
$scope.items = dataService.data.items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function() {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
}
]).
controller('appController', ['$scope', '$modal', '$log', 'DataService',
function($scope, $modal, $log, dataService) {
$scope.data = dataService.data;
$scope.showModal = function() {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'myModal'
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
}
]);
Had a similar issue and declared the modal controller without adding it to the module, like this:
var ModalInstanceCtrl = ['$scope', '$modalInstance', 'items', function ($scope, $modalInstance, items) { ... }
With no other changes required this syntax works with minification as well.
The simple way to do this is use $inject:
// inject the controller with the following dependencies
ModalInstanceCtrl.$inject = ['$scope', '$modalInstance', 'items'];
Change the controller method to a named function :
function ModalInstanceCtrl($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
I have written a blog article on this subject and includes how to write tests for directives that use $inject:
transitioning-to-angular-2-0-part-2