Reputation: 3958
I am confused with the scope in ui modal controller when using 'controller as in the ui router. I tried to keep using the same controller (CompanyCtrl) as the controller for modal so that I can add new created company data into the exist company scope. In side of the openModal function, I assign the scope to a modalInstance so that I can use this instance to close or do whatever I want with the modal. However, when I click the close button, the modalInstance in the closeModal is undefined somehow.
//////// My company module and controller
var CompanyCtrl = function ($modal) {
this.modalTitle = 'Create Company';
this.openModal = function() {
this.modalInstance = $modal.open({
animation: true,
controller: 'CompanyCtrl as lsmodal',
bindToController: true,
template: '<ls-modal><ls-create-company></ls-create-company></ls-modal>'
});
};
this.closeModal = function() {
console.log(this.modalInstance); // undefined ????????
};
};
angular.module('company', []);
angular.module('company').config(function ($stateProvider) {
/* Add New States Above */
$stateProvider.state('master.company', {
url: '/company',
templateUrl: 'modules/company/company.html',
controller: 'CompanyCtrl as company'
});
})
.controller('CompanyCtrl', CompanyCtrl);
//////// ls modal html
<div class="modal-header">
<button type="button" class="close" ng-click="lsmodal.closeModal()">×</button>
<h4 class="modal-title">{{lsmodal.modalTitle}}</h4>
My questions are
Since they shared the controller, why everything I assigned to this/scope
in the openModal function is gone in the closeModal. Is that because I create another new scope using CompanyCtrl as lsmodal. how to fix this?
Is this good design sharing the same controller? or create a separated controller for modal. If create a separated controller, how I can append the new created company object to the company list so that the company list in the html will updated as well.
Upvotes: 0
Views: 439
Reputation: 6676
Yes, controllers are not singletons, so every time you assign the controller to a template, you are effectively creating a new instance of it. I'm not sure this can be avoided. That is precisely why you are seeing undefined. The this.modalInstance variable that you are trying to print out in the dialog controller only exists in the parent controller's context.
Controllers can/?should? be thought of as viewmodels -- that is, they should be a programmatic representation of the view. If you have different views, then it makes sense to have different controllers. If you need data in the modal that exists in the original controller, you can alway 'pass' the data via resolves like so:
var modalCtrl = function($scope, $modalInstance,DataYouExpectFromParentCtrl) {
$scope.data = DataYouExpectFromParentCtrl;
$scope.ok = function () {
$modalInstance.close(/* pass anything here that the parent will receive after OK */);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
var CompanyCtrl = function ($modal) {
this.modalTitle = 'Create Company';
this.openModal = function() {
var modalInstance = $modal.open({
animation: true,
controller: 'ModalCtrl as lsmodal',
bindToController: true,
template: '<ls-modal><ls-create-company></ls-create-company></ls-modal>',
resolve: {
DataYouExpectFromParentCtrl: this.data;
}
});
modalInstance.result.then(function (dataFromModal) {
// handle data returned if OK
}, function () {
// handle cancellation
});
};
};
Upvotes: 2