Angular Material $mdPanel doesn't have a close() method - javascript

I am using angular material $mdPanel, i can display it using the open() method but i can't remove it (using close button like the demo). The documentation is not clear about that, the close method doesn't work. Is there any solution for that ?
$mdPanel documentation

When you call $mdPanel.open(), it returns a promise. The call to the promise contains a reference to the created panel. You can call close() on that.
$res = $mdPanel.open(...);
$res.then(function(ref) {
$scope.ref = ref;
})
Later on, to close, call:
$scope.ref.close();

There is no close() method on $mdPanel it is instead a method on the panel reference, which is passed on the first argument to the controller for that panel. So to be able to close the panel you need to pass a controller function in your panel definition similar to below.
Hope this helps!
var config = {
...,
controller: PanelController,
controllerAs: 'panelCtrl',
template: '<div><div>Some content</div><button ng-click="panelCtrl.close()">Close</button></div>',
...
};
function PanelController(panelRef) {
this.close = function () {
panelRef && panelRef.close();
};
}

You can inject the mdPanelRef inside a controller and then call mdPanelRef.close()
var config = {
...,
controller: PanelController
};
function PanelController(mdPanelRef) {
this.close = function () {
mdPanelRef.close();
};
}

Related

jQuery return like this

I have problems with jQuery callbacks
I try to do like this.
MainController.js
mapController = $.fn.mapController();
getMapController = function() {
return mapController;
};
mapController.js
(function ( $ ) {
$.fn.mapController = function(options) {
let mapController = {};
let settings = $.extend({
save: function(data) {}
}, options);
mapController.openModal = function () {
//OPEN MODAL
}
return: mapController
}
}(jQuery));
nextController.js
function setPlace() {
getMapController({
save: function(data) {
console.log("TEST")
}
}).openMapModal();
}
So... I try get mapController in nextController from getMapController method but not workink callbacks...
How I can get callbacks in nextController.js?
It seems like you have introduced some confusion by naming a jQuery plugin with the same name as the object that plugin returns. Both are called mapController. This is not a problem on itself, but in setPlace you call mapController as if it it is the jQuery plugin (passing it options), but it is in fact the object returned by it (see MainController.js), which is not a function.
So I think you'll want to change the MainController code, and make the global mapController variable equal to the jQuery plugin:
mapController = $.fn.mapController;
// ^^^^^ remove parentheses.
Like mentioned already, make sure to remove the syntax error in the return statement in the MapController; it should not have a colon after it.
getMapController() returns a function, you have to call it with ():
function setPlace() {
getMapController({
save: function(data) {
console.log("TEST")
}
})().openMapModal();
}
Also, you have an erroneous : on this line:
return: mapController
It should just be:
return mapController

AngularJS accessing parent controller properties from modal controller - resolve vs $scope

Learning AngularJS is a Work In Progress for me so I just want to understand why/when we should use one over another in particular case below. Is it just matter of taste or more than that? See examples below.
In both cases, when user clicks OK button, create() function of parent controller is called from child controller.
RESOLVE STYLE
CreateController
...
var vm = this;
vm.create = create;
function create() {
console.log('Created!');
}
vm.openCreateModal = function() {
vm.modalInstance = $uibModal.open({
...
resolve: {
create: function() {
return create;
},
// Others if any
}
});
}
...
CreateModalController
...
vm.ok = function() {
create();
$uibModalInstance.close('ok');
};
...
SCOPE STYLE
CreateController
...
var vm = this;
vm.create = create;
function create() {
console.log('Created!');
}
vm.openCreateModal = function() {
vm.modalInstance = $uibModal.open({
...
scope: $scope,
resolve: {
}
});
}
...
CreateModalController
...
vm.ok = function() {
$scope.$parent.vm.create();
$uibModalInstance.close('ok');
};
...
Update
The actual reason why I ask this question is, accessining/injecting parent/root/container like objects of one service/controller in/to another controller/service is considered as a "bad practise" in some languages/frameworks I use.
The idea of resolve is that it will run that first before initializing the rest of your code. Generally you would use resolve in your routing like so:
$routeProvider
.when('/', {
templateUrl: "views/view.html",
caseInsensitiveMatch: true,
resolve: {
load: function() {
localStorage['Location'] = "/View";
}
}
})
In the above example resolve will fire the load function before my controller is ever initialized. On the other hand scope is used to bind directly to something in a controller or directive. You should use scope when triggering functions and binding to values between controllers and directives.
To add to this based on the comments below, if the resolve fails it will reject the modal and the window will not open.

$uibModal: get instance from method

I'm using modals via method, like:
this.showModal = function () {
return $uibModal.open({...});
}
and then in some method i call this function:
this.showModal().result.then(function (someResult) {...});
but how can i use dismiss, using method call?
becouse i use it without method, i can close my modal so:
$uibModal.open({...}).result.then(function (someResult) {
this.$dismiss();
})
but i have no clue, how to use dismiss, when i use methods promise...
maybe somebody have an idea?
The open method returns a modal instance with open, closed,dismiss ,close,rendered ,returned method.
In your case it is this.showModal is modal instance.
SO, you can call the close the method like this.
var self = this;
self.showModal = function () {
return $uibModal.open({...});
}
//close the modal
self.showModal.close();
You could store the modal in an object, either in the scope or move this to a service, and then call dismiss on the modal object
var modalInstance;
this.showModal = function () {
modalInstance = $uibModal.open({...});
return modalInstance;
}
and when using the promise
this.showModal().result.then(function (someResult) {
modalInstance.dismiss('cancel');
});
What I usually do is making a modal instance :
$scope.doSomething = function(){
var modalOptions = {...};
openModal(modalOptions);
}
function openModal(modalOptions) {
$scope.myModalInstance = $uibModal.open(modalOptions);
$scope.myModalInstance.result.then(function () {
//success callback
}, function () {
//error callback;
});
}
Later if i want to call close or dismiss simply call $scope.myModalInstance.close() and $scope.myModalInstance.dismiss('cancel').

calling a function on url call in angularjs

I am very new to angularjs and require help on calling a function on url call.
I am directly accessing the query params from url using
http://localhost/index.html#/?defined=true&var1=value1&var2=value2&
$location.search()['defined'];
now , within my controller I have a function 'caller' which is being called on events like ng-change , ng-model etc. on the html page which works fine
angular.module('ngAp').controller
('ngCntrl',function($scope,$http,$location{
$scope.caller = function() {
// code logic
}
}
What I am trying to do is to call the function 'caller' when I directly access the above url
$location.search()['defined'];
if (defined == "true" )
{ //call the caller function.
}
I have no idea how can I call the function when i directly call the url.
Any help is greatly appreciated.
If you take a look at the docs for $location - https://docs.angularjs.org/api/ng/service/$location
It has some events you can use like $locationChangeStart. But it's better to bind to this event in angular.module('ngAp').run(...).
angular.module('ngAp').run(moduleRun);
function moduleRun ($location, $rootScope) {
$location.on('$locationChangeStart', function (event, newUrl, oldUrl, newState, oldState) {
var defined = $location.search()['defined'];
$rootScope.defined = defined //you can assign it to $rootScope;
if (defined === "true" ) {
//call the caller function.
}
})
}

AngularJS use a global scope function inside another

I have the following AngularJS function called editlocation that opens a Modal window that I can edit three pieces of data.
After the result I want to be able to run plotmarkers this is used in another instance of an ng-click. I have tried the following but it doesn't work. I also tried placing it inside the ModalInstanceCtrl2 controller too, but no luck.
$scope.editlocation = function (locations) {
var locationToEdit = locations;
var modalInstance = $modal.open({
templateUrl: 'template/modal-edit-marker.html',
controller: ModalInstanceCtrl2,
resolve: {
locations: function () {
return locationToEdit;
}
},
scope: $scope.$new()
});
modalInstance.result.then(function (selectedItem) {
locationToEdit.title = selectedItem.title;
locationToEdit.gps = selectedItem.gps;
locationToEdit.desc = selectedItem.desc;
$scope.plotmarkers;
}, function () {
console.log('Modal dismissed at: ' + new Date());
});
};
$scope.plotmarkers = function() {
//things will happen here
};
You aren't actually calling the function here. Try this:
$scope.plotmarkers();
Unless plotmarkers in in the same controller/scope (ModalInstanceCtrl2) you are calling it that won't work. a far better approach would be to emit or broadcast an event that would let know every interested party that markers should be plotted you can do it either using the controllers scope or the $rootScope if you have it injected.

Categories