I have 2 routes:
app.config(['$routeProvider', '$locationProvider', function(
$routeProvider, $locationProvider) {
$routeProvider.
when("/list/:class", {
controller: "listController",
templateUrl: "DatabaseObject",
reloadOnSearch: true
}).
when("/edit/:class/:id?", {
templateUrl: "editortemplate"
}).
otherwise("/custombrowsingstartpage");
}]);
They both work fine!
What I would like is to be able to render the "editortemplate" of one of the routes within a modal window from the "/list/:class" route.
Within my "listController" I have the modal opening function:
$scope.showEditorPanel = function (size, a, b) {
//console.log($scope);
var modalInstance = $modal.open({
animation: true,
//templateUrl: '#/edit/'+b+'/'+a,
templateUrl: 'editortemplate',
controller: 'editorController',
size: size,
backdrop: true,
scope: $scope
});
The template renders well but I don't know how to pass it the class and id variables the template requires(as shown in its route).
I tried defining route with variables(class== var b, id== var a) instead of template url but no luck:
//templateUrl: '#/edit/'+b+'/'+a,
If you add a 'resolve' object you can send what you want, I believe this is the "Angular" way to do this with $modal :
$scope.showEditorPanel = function (size, a, b) {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'editortemplate',
controller: 'editorController',
size: size,
backdrop: true,
resolve: {
scope: function () {
$scope.properties.class = a;
$scope.properties.id = b;
return $scope.properties;
}
}
});
To pass data to the modal window, you need to use the resolve method of the modal instance. It works just like the same property in the router:
$scope.showEditorPanel = function (size, a, b) {
var modalInstance = $modal.open({
...
resolve: {
class_id: function () { return $scope.class_id }
}
});
Then you need to require that in the the modal window's controller:
function editorController ($modalInstance, $scope, class_id) {
// use the class_id ...
$scope.class_id = class_id;
}
This fixes the 'class_id' in the explicit requirements of the modal controller and will help with troubleshooting down the road. You could have passed it in "secretly" via the $scope, but this is not a good idea (I categorically avoid the $scope property in $modal!). Explicit code is good code!
I just had to define the expected variables as $routParams:
$scope.showEditorPanel = function (size, a, b) {
//console.log($scope);
$routeParams.class=b;
$routeParams.id=a;
var modalInstance = $modal.open({
animation: true,
//templateUrl: '#/edit/TissueSample/'+a,
templateUrl: 'editortemplate',
controller: 'editorController',
size: size,
backdrop: true,
scope: $scope
});
Related
I couldn't come up with normal title. Sorry for that.
So the problem is that in a big project, with big business logic there are a lot of modals. And every new modal is the same code with little changes, like templateUrl, controller and such things. This is how pop up is getting called now:
return uibModal.open({
templateUrl: current.path + 'url.html',
controller: 'AppController',
windowClass: 'PopUp',
size: 'md',
resolve: {
disabled: [function () {
return scope.disabled;
}]
}
}).result.then(function( comment ){
record.comment = comment;
})
And this routine never ends. So what I'm interested in is - what is the best practice to reduce the same code(same to this situation) in your project? Should you use service? Or just create global function?
In AngularJS you should always avoid global functions. Services were created for this purpose. I also use $uibModal and was tired of writing the same thing over and over again.
I made a ModalService which allowed me to abstract away a lot of the repetitive code:
function ModalService() {
var ModalService = this;
ModalService.basicModal = function(options) {
var _options = options || {};
return $uibModal.open({
animation: angular.isDefined(_options.animation) ? _options.animation : true,
keyboard: angular.isDefined(_options.keyboard) ? _options.keyboard : true,
backdrop: _options.backdrop || 'static',
size: _options.size || 'sm',
templateUrl: _options.templateUrl || 'templates/modal-message.html', //default template in case user does not provide one
controller: _options.controller || ModalMessageCtrl, // a default controller in case user does not provide one
controllerAs: _options.controllerAs || 'vm',
resolve: options.resolve || {}
});
};
ModalService.simpleModal = function(options) {
...
};
}
You can define many varieties of modals that can be invoked easily from the controller:
ModalService.basicModal();
ModalService.simpleModal();
// etc...
And all of these can accept optional parameters to customize the modal:
ModalService.basicModal({
size: 'lg'
});
ModalService.simpleModal({
templateUrl: "my-custom-template.html",
controller: function($scope) {
//some custom inline controller
}
}).result.then(function() { //do something });
// etc...
You can use $uibModalProvider.options to set the default options during the configuration phase of the application.
app.config(function($uibModalProvider) {
$uibModalProvider.options = {
windowClass: 'PopUp',
size: 'md'
};
});
If you're using UI Bootstrap 2.1.0 or greater you can also leverage angular's component based architecture to remove some of the extra cruft when opening a modal.
Given a component defined as follows:
app.component('myModal', {
bindings: {close: '&', dismiss: '&', resolve: '<'},
controller: MyModalController,
templateUrl: 'myModal.html'
});
You can leverage the component in a modal as follows:
$uibModal.open({
component: 'myModal',
resolve: {
// pass data to component
}
}).result.then(function() {
// Modal closed
}).catch(function() {
// Modal dismissed
});
I want to update some value of a $modal in AngularJS but unable to understand how I can do this. Sample code is below:
var modalInstance;
function setupCall(data) {
var templateURL = 'partials/Chat.html';
var cssClass = 'medium-Modal';
modalInstance = $modal.open({
backdrop: "static",
keyboard: false,
backdropClick: false,
windowClass: cssClass,
templateUrl: templateURL,
controller: function ($scope, $modalInstance) {
$scope.updateStatus=function() {
...
}
}
});
modalInstance.result.then(function() {
});
}
// first time i call this function to open model
setupCall(event);
Now when model open successfully and if I received some update from service and I again want to show updated values in a model then how I can call updateStatus() from outside the model. I try to using
modalInstance.updateStatus(..) but it is not working. Can someone tell me a proper way to do this?
You can pass a scope option to $modal, and then use AngularJS events
var modalScope = $rootScope.$new();
myService.doSomethingAsync(function (data) {
$rootScope.$emit('some event', data);
});
$modal.open({
scope: modalScope,
controller: function ($scope) {
/* ... */
$scope.$on('some event', function() {
$scope.updateStatus();
});
}
});
You can use $broadcast to call that method. For example, after you received update from your service in your view's controller (where you are calling setupCall or launching the modal), do this:
$rootScope.$broadcast("dataUpdatedFoo", {newData: "bar"));
Now, inside your controller of modal, register a listener for this:
$scope.$on("dataUpdatedFoo", function(e, data) {
$scope.updateStatus();
});
Thanks everyone. I resolve this by adding custom eventlistener.
var listeners = [];
function _addEventListener(listener) {
listeners.push(listener);
return listener;
}
function _removeListener(listener) {
for (var i=0; i < listeners.length; i++){
if (listeners[i] === listener){
listeners.splice(i, 1);
break;
}
}
}
function setupCall(data) {
......
modalInstance = $modal.open({
backdrop: "static",
keyboard: false,
backdropClick: false,
windowClass: cssClass,
templateUrl: templateURL,
controller: function ($scope, $modalInstance) {
var listener = _addEventListener(function (event) {
$log.info("chat msg: "+JSON.stringify(event));
});
$scope.$on('destroy', function () {
_removeListener(listener)
});
...
Like we pass params through modal, as did in below by resolve example :
$scope.someFunction = function(item) {
item.root = true;
modalInstance = $uibModal.open({
animation: true,
controller: 'newController',
templateUrl: '/views/modals/somePage.html',
resolve: {
params: function () {
return { item: item};
}
}
});
};
I am not sure how to pass params in ionicModal ??
$ionicModal.fromTemplateUrl('main/templates/viewPage.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
Is there an option along with animation as in above ionicModal code?
Help is much appreciated!
You do not need to pass any data. Your parent scope is already passed as
scope : $scope
So you can take your data as scope.item.
Please follow this URL
https://forum.ionicframework.com/t/how-to-pass-data-from-parent-controller-to-ionicmodal/2030/2
I am using Modal (ui.bootstrap.modal) and I have seen 2 different implementations for this:
1. Declare the controller modal instance in the modal declaration
/* 1 file ModalDemoCtrl.js*/
angular.module('ui.bootstrap.demo')
.controller('ModalDemoCtrl', function ($scope, $uibModal, $log) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: function(){
// stuff
},
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
});
2. Declare the controller modal instance separate from the parent controller
/* first file ModalDemoCtrl.js*/
angular.module('ui.bootstrap.demo')
.controller('ModalDemoCtrl', function ($scope, $uibModal, $log) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller:'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
});
/* second file ModalInstanceCtrl.js*/
angular.module('ui.bootstrap.demo')
.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items) {
//stuff
});
Questions
a) Which implementation is suitable for a large angular web application ?
b) With implementation 2 will I have dependency issues later on, because of the members that will be resolved and passed to the controller as locals (resolve (Type: Object)) ?
c) With implementation 1 will I increase the number of code lines in my js file ( the controller) and will be harder to understand the logic ?
When I am trying to open a modal on ng-click the scipe variables is getting lost.
var modalInstance = $modal.open({
templateUrl: 'partials/create.html',
controller: 'AppCreateCtrl',
scope: $scope // <-- I added this
});
You should pass data using the resolve property like this:
var modalInstance = $modal.open({
templateUrl: templateSrv.templateUrl('partials/create.html'),
controller: modalBootstrap,
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
var result = {};
result.scope = $scope;
return result;
}
}
});
modalInstance.result.then(
function (dataPassedFromModalConroller) {
//this is called when the modal is closed
},
function (dataPassedFromModalConroller) { //Dismiss
//this is called when the modal is dismissed
}
);
Specify the controller for the modal instance like this (we do this in another file):
var modalBootstrap= function ($scope, $modalInstance, data) {
$scope.modalInstance = $modalInstance;
$scope.scope = data.userId;
};
modalBootstrap['$inject'] = ['$scope', '$modalInstance', 'data'];
Your modal template would look something like this:
<div ng-controller="AppCreateCtrl">modal content here</div>