Angular how to get access to $scope var from modal - angularjs

I have a page where I have a button to launch a modal. Both pages has its own controllers. The question is how to get variable from page in modal controller?

You pass data to your modal controller using resolve.
var modalInstance = $modal.open({
templateUrl: 'template.html',
controller: 'MyModalCtrl',
resolve: {
variableToPass: function () {
return $scope.items;
}
}
});
Then you define your modal controller like this
myApp.controller('MyModalCtrl', ['$scope', $modalInstance'', 'variableToPass', function($scope, $modalInstance, variableToPass) {
...
}]);
Alternatively, or complementary, you can pass the whole $scope like this
var modalInstance = $modal.open({
templateUrl: 'template.html',
controller: 'MyModalCtrl',
scope: $scope
});

Related

moving angular modal controllers into separate files

I have a page controller on my site that includes several modals. Some of the modal controllers are getting robust, and I would like to move them into separate controllers without losing the scope of the outer page controller (the modal controller uses some of the page controllers functions and properties) - is this possible? So far I am getting errors to anything which references the outer controller. Here is a simple example of how I have it set up:
the page controller:
angular.module('myApp')
.controller('outerCtrl', function(MetaService) {
var thisCtrl = this;
thisCtrl.someFunction = function() {
//some cool functionality that will elvaluate something
}
function optionsModal() {
var PageCtrl = thisCtrl;
$uibModal.open({
'controller': 'scripts/controllers/optionsModal.js',
'controllerAs': 'ModalCtrl',
'templateUrl': 'views/modals/optionsModal.html',
'size': 'md'
});
}
});
the modal controller:
angular.module('myApp')
.controller('optionsModalCtrl', function(MetaService) {
var modalCtrl = this;
function giveOptions() {
if (PageCtrl.someFunction()) {
//offer some option
} else {
//offer a different option
}
}
});
Here is the example from official page:
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
scope: $scope, // pass parent scope to modal instance
resolve: {
items: function () {
return $scope.items;
}
}
});

Passing data between modal and controller

How can I make data available in a controller? I have created a really simple Plunk that should show data on the $scope in a modal. I’ll then need to update the data, and only update $scope on clicking “ok”. Clicking “cancel” will discard the changes.
But before I get to that step, I need to make the scope available to the modal. Most of the examples use two controllers. Do I need another controller as in this example: Passing Data to Twitter Bootstrap Modal in Angular? In my controller I have the following:
$scope.open = function(){
var modalInstance = $uibModal.open({
templateUrl: 'modal.html',
controller: 'ModalInstanceController',
resolve: {
users: function() {
return $scope.users;
}
}
});
};
How can I display the users in the template? The plunk is here: http://plnkr.co/edit/FuXjSwtljQtFYOtFRV18?p=preview
To be able to access scope of the controller you need to pass scope object to the modal when creating an instance of it:
$scope.open = function() {
var modalinstance = $uibModal.open({
scope: $scope,
templateUrl: 'modal.html',
resolve: {
users: function() {
return $scope.users;
}
}
})
};
This way Angular will create child scope of the controller $scope so you will be able to access items inside of modals scope:
Demo: http://plnkr.co/edit/0m9oktX2JHFmeiaDfOpO?p=preview
You can access scope in modal -
$scope.open = function(){
var modalinstance = $uibModal.open({
templateUrl: 'modal.html',
scope:$scope
})
};
you can do it with just one controller, is just that is a "dirty" solution, because both html files will share the same controller, which is potentially an issue.
the problem you are facing is that in the modal you don't have a defined scope, so the foreach (ng-repeat) you are doing is not getting any elements
you can fix it easily by changing your modal.html to
<div ng-controller="modalController"><div class="modal-header">
<h3 class="modal-title">Modal</h3>
</div>
<div class="modal-body">
<p>Existing users:</p>
<ul>
<li ng-repeat="user in users">{{user}}</li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="button">Close</button>
</div>
</div>
as you see, now this modal has a controller (the same as the main window) and so will have a scope
or else just pass the scope to the modal definition adding
var modalinstance = $uibModal.open({
scope: $scope,...
is dirty, and you are "polluting" the scope, but it works :)
Here is some code from my current project it works as expected if you want to use any ng-click on the modal your function has to reside in ModalInstanceController
app.controller('dashboardCtrl', function ($scope, $rootScope, $location, $http, Data, $uibModal ) {
$scope.users = '';
$scope.open = function(){
var modalInstance = $uibModal.open({
templateUrl: 'modal.html',
controller: 'ModalInstanceController',
resolve: {
users: function() {
return $scope.users;
}
}
})
}
});
app.controller('ModalInstanceController', function ($scope, $uibModal, $uibModalInstance, users, $rootScope, $http, Data) {
$scope.ok = function () {
$uibModalInstance.close($scope.selected.item);
}
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
}
$scope.users = users ;
$scope.selected = {
users: $scope.users[0]
};
});

Can't update $scope on modal close

I have a controller tied to my view via routing.
Example in App.js I have the following:
when('/about', { templateUrl: 'views/about.html', controller: 'appAboutCtrl' }).
I have another controller for Modal specific actions. I need this since it is a login action that applies across pages, and for that reason, it is it's own controller versus repeating the login functionality in every controller.
My modal does what it is supposed to do, but when I close it, I need it to update the $scope on the page to show/hide an item by setting something akin to:
$scope.isLoggedIn = true;
However, the scope is not updating. I have seen something like this here: https://github.com/angular-ui/bootstrap/issues/2110#issuecomment-54551321 but given the complexity of my login, I need it to be in its own controller... separate of the controller driven my view.
Here is the call to my Modal and controller specific modal in the controller tied to the view I open it from (about.html and appAboutCtrl):
// Open Modal for Login
$scope.login = function () {
var modalInstance = $modal.open({
templateUrl: 'templates/login.html',
controller: 'appLoginCtrl',
size: 'lg'
});
}
Here is where I try to set the scope on modal close in appLoginCtrl:
$scope.ok = function () {
$modalInstance.close();
$scope.isLoggedIn = true;
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$scope.isLoggedIn = true;
};
I can reload the view on modal close, but can't set the $scope as follows:
$scope.ok = function () {
$modalInstance.close();
$route.reload();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$route.reload();
};
How can I set the $scope on Modal close so that when I close the modal, my view registers the change? My $scope is tied to a ng-show to show/hide an item on login.
You can use resolve option to bind variables.
var modalInstance = $modal.open({
templateUrl: 'templates/login.html',
controller: 'appLoginCtrl',
size: 'lg'
resolve: {
isLoggedIn: function () {
return $scope.isLoggedIn;
}
}
});
or you can pass the parent controller's scope to the modal scope
var modalInstance = $modal.open({
templateUrl: 'templates/login.html',
controller: 'appLoginCtrl',
size: 'lg',
scope: $scope
});

angularjs $modal close modal

Im trying to make an angularjs Modal service.
I have an controller that opens some modal, in that modal i call original controller functions or access some variables, this part i can make it already.
I just cant close modal without clicking cancel or ok buttons, o want to make some operations in the modal, call some werbservices and the close modal manually.
Can anyone help me?
I made an working plunker here:
plunker
var modalInstance = $modal.open({
templateUrl: 'myModalContent2.html',
controller: ModalInstanceCtrl,
size: size,
scope: $scope
});
To close a $modal that you have opened you can follow these steps.
1) Inject $modalInstance into the controller that you specified when you created the modal. In your case you called it ModalInstanceCtrl.
2) Have a function in your ModalInstanceCtrl that calls .close() on $modalInstance.
your ModalInstanceCtrl should look something like this
angular.module('myCoolApp')
.controller('ModalInstanceCtrl', function ($scope, $modalInstance) {
$scope.closeModal = function(){
$modalInstance.close();
}
});
$scope.myData='all data can be';
$scope.myModalInstance = $modal.open({
templateUrl: 'app/myOpen.html',
controller: 'myOpenController',
size: 'lg', //modal open size large
backdrop: 'static',
keyboard: false,
resolve: {
myData: function () {
return $scope.myData;
}
}
});
$scope.modalClose = function (){
$scope.myModalInstance.close();
}

How to call Controller?

var modalInstance = $modal.open({
templateUrl: 'views/modals/addDevice.html',
controller: ModalCtrl
});
modalInstance.result.then(function (newDevice) {
});
I will implement it in this way:
app.controller("ModalCtrl", function( $scope, $modalInstance ) {
});
But only this way is accepted:
var ModalCtrl = function ($scope, $modalInstance) {
};
Why this happens?
When registering a controller the following way:
app.controller("ModalCtrl", function( $scope, $modalInstance ) {
});
You haven't declared a ModalCtrl variable so in the following case ModalCtrl would be undefined:
var modalInstance = $modal.open({
templateUrl: 'views/modals/addDevice.html',
controller: ModalCtrl
});
You can provide the controller name as a string instead:
var modalInstance = $modal.open({
templateUrl: 'views/modals/addDevice.html',
controller: 'ModalCtrl'
});
I think you are having issues because the value for your controller name needs to be in quotes -
var modalInstance = $modal.open({
templateUrl: 'views/modals/addDevice.html',
controller: 'ModalCtrl' // <-- this needs to be in quotes
});
This is defining your controller class:
var ModalCtrl = function ($scope, $modalInstance) {
};
you need to create an instance of the class:
var instance = new ModalCtrl(args)
Use cotes for the controller name. That will work fine.

Resources