I am using $modal for opening modals.
I have a modal that contains a ui-view. States using the ui-view need to wait until the modal has been added into the DOM, otherwise the states will not find the ui-view to load templates into.
Anyone have a good way for delaying the loading of a template? I have considered a promise that resolves once the modal's controller has been initialized, but I fear it is overcomplicating things.
Thanks
So if anyone is going down the same road, I ended up using Jquery-based foundation for my modal control, rather than the angular-foundation $modal service. With the jquery foundation modals, I can add a hidden modal div to my main template, containing the ui-view. So there is never any waiting for the modal to be appended to the DOM. Activating the modal is just unhiding the modal's div. This solved all timing issues and works as intended.
Related
Problem:
Anyone know why in my cb.register function below, my Modal window closes OK, but the $location.url('/dashboard') does not properly run?
I don't get any console errors, and the page does not redirect. However, console.log('TRANSITION DONE') still prints out in the code below after the modal window closes, so I know the event is being recognized:
Code:
app.controller('userController', ['$scope', 'userFactory', '$location', function($scope, userFactory, $location) {
var cb = {
register: function(createdUser) {
// Closes Modal window:
$('#myModal').modal('hide');
// Runs after close with completed transition effects:
$('#myModal').on('hidden.bs.modal', function (e) {
console.log('TRANSITION DONE');
$location.url('/dashboard');
})
},
};
}]);
Questions:
Why does the $location service not behave properly when nested inside of my .on() function?
Should I be using angular-ui instead? (Of which I was not familiar until researching solutions to this issue, and instead started my project by framing out all the views first using bootstrap3 and including the JS files, etc).
What I've Tried:
I've tried passing the $location parameter into the .on()'s callback function, along with e, but that made no real change and the function should still have access to $location in the larger scope.
Console logging $location or $location.url works properly, so I know the methods are accessible in the scope.
Moving the $location function outside of the on() function does load the dashboard page, however the fade-out modal close does not complete. A light-grey transparent BG is overlaying my dashboard page, which is why I chose to utilize the hidden.bs.modal event per the documentation: http://getbootstrap.com/javascript/#modals
// Closes window:
$('#myModal').modal('hide');
// Redirects to page but fade-out on Modal not completed:
$location.url('/dashboard');
Desired Behavior/Pseudo-Code:
Modal window closes (when callback runs)
After Modal fade out:
$location.url('/dashboard') runs, loading dashboard page
Thank you to any angular/bootstrap ninjas whom can help!
Why does the $location service not behave properly when nested inside of my .on() function?
You're directly using Bootstrap modals in your application -- which is OK. But, this requires you to manipulate the modal with jQuery. It is not advisable to use jQuery in an AngularJS application as AngularJS has its own methods of DOM manipulation and therefore you shouldn't manually manipulate the DOM via jQuery.
To answer your question, since you're using jQuery to directly manipulate the DOM, it is likely that AngularJS' digest cycle has not picked up on the modal closing. You could get around this by telling AngularJS to activate a digest cycle via $scope.$apply(). However, this will easily dirty up your code and just doesn't make sense according to best AngularJS principles.
Should I be using angular-ui instead? (Of which I was not familiar until researching solutions to this issue, and instead started my project by framing out all the views first using bootstrap3 and including the JS files, etc).
Yes. I would highly suggest using angular-ui. As per the documentation:
This repository contains a set of native AngularJS directives based on Bootstrap's markup and CSS. As a result no dependency on jQuery or Bootstrap's JavaScript is required.
As you can see, all of the Bootstrap functionality has been wrapped up into AngularJS directives that can easily be dropped into your application without worrying about jQuery.
I got the following problem in angular and don't really know how to get around it
When you click on the modal links a modal windows should open, each modal window should have it's own controller
When clicking on the sidebar I want a the respective sidbar controller to load as well as the linked template url.
I have tried different setups but using normal ng-view all content keeps loading in the sidebar content area.
Any ideas on how to use multiple controllers and views in this manner?
i don't 100% understand your question, but try using ng-include instead of the ng-view. You can use ng-view for the whole page and you can load dynamic partials through controllers. https://docs.angularjs.org/api/ng/directive/ngInclude
What's the best way to have my views appear in a popup modal?
I have the main dashboard of my app, and then whenever the user wants to add or edit an item on the dashboard I want this to be done via a form in a popup modal.
I know I can use jquery to handle the showing and hiding of the popup. But is there an angular way to do this, or is jquery acceptable in this scenario?
Check this out and go down to the modal section. This looks nice and clean. There is an example of the html and javascript there for you. Your view is a template and can be a html file or inline html inside the javascript.
http://angular-ui.github.io/bootstrap/
Much like everything in Angular, there are a number of ways you could do this. Perhaps the most simple way would be to have the HTML of the modal be hidden by either ng-show or ng-hidein conjunction with ng-mouseover.
I'm actually doing this right now and decided to use jquery ui for the modal. Dragging and resizing is hard to do and my modal requires that. I wrap the modal call in a directive so modal pops up onclick. The mistake I made was using jquery append to add new html. Don't do this. Use template or templateUrl and then put that in your modal. This will ensure all scope vars in your modal will communicate with your controllers.
Is there the AngularJS way to close other popovers on creating a new one. For example, this code:
http://plnkr.co/edit/wx7KbFDb9du6TnaFioy2?p=preview
I can do it by falling back to jQuery, is there any other way?
Since popovers could potentially exist anywhere in your dom tree. You would need to either create your very own publisher subsriber system or use the built in $broadcast and $on methods for angularjs.
When you have a popover show up you just need to call $rootScope.$broadcast(the popover you just opened) and have a $scope.$on in all of the popover places that listen to this event and close if they are open.
Check out the docs for more information http://docs.angularjs.org/api/ng.$rootScope.Scope#methods_$on
Hope this helped
I created a plunker to recreate the problem:
http://plnkr.co/edit/sPPB0Cq0PUg1jmzzZtXh
It contains a mini angular js app with angular-ui-bootsrap.
index.html - main html file with js includes and a ng-view div.
other.html, main.html - the views
app.js - main angular js file with declaration of app.
modal.js - some js stuff related to the modal.
I wrapped $modal with my own service that responds to a
broadcasted "show-modal" event by showing a modal and created a
directive that attaches to elements as an attribute and
emits/broadcasts this event.
The problem:
I'm trying to use $modal service to open a modal window.
It opens, then after I close it, i cannot open it again.
Actually, when trying to open again, it appears to not open. but when navigating to another location in the angular app the modal suddenly appear(or modals if you clicked many times) .
I'm kinda lost and the documentation didn't really help me.
Can anyone check it out and tell me what am i doing wrong?
After reviewing some cases in which the modal does work, i think i got a solution up at the same plunker i put before
http://plnkr.co/edit/sPPB0Cq0PUg1jmzzZtXh
You have to use $modalInstance to .close() and .dismiss() the modal.
the docs suggest one could use the injected $close $dismiss functions but using these caused the problem for me...
I left the problem as is and implemented the solution in new files so you can review both (at your pleasure).
--- EDIT ---
if all fails $scope.apply() (or $rootScope.apply())
i tried to scope.apply after issuing the signal to open the modal and it successfully showed the modal immidietaly instead of on the next cycle (which was triggered for example by going to another page)