I'm listening to the event $routeChangeStart and I want to be able to redirect the user to another controller based on a condition. I am able to visually redirect him to another controller with $location.path() but the original controller still gets called. How can I prevent it? event.preventDefault() doesn't work.
Related
Ok so i have a component i made up with a form. I would like to alert the user that he has unsaved data (if he has) when the user clicks on another link.
Now if i would not be tied to ember i would put a flag on a change event and add a window unload listener to show the actual message, However,
Since im not really leaving the window this is not getting called.
Is there any Ember event i can attach a handler to? like a change route intent event of some kind
Im interesting in knowing which is the correct event for the leaving route action, not in the something change logic.
ive tried this so far on the didInsertElement( ) method
Ember.$("body").on('unload',()=> alert('it works'));
Ember.$("window").on('unload',()=> alert('it works'));
Ember.$("body").on('unload','body'()=> alert('it works'));
any ideas?
Have you had a look at the willTransition method on your route? That will be the place to do it. Have a read of this guide to preventing and retrying transitions, as well as the willTransition method's documentation. Hope that helps!
You can catch transition event on route. It's meant to be used for this use case.
There is also action when component is being destroyed but that is meant for teardown.
In single page application, I am using HTML5 Mode routes. Lets say someDomain.com/#/credits becomes someDomain.come/credits. Changing the routes on the click of tab.
So lets say I have tab1 tab2 tab3 so routes fr corresponding tabs are someDomain.com/tab1 someDomain.com/tab2 someDomain.com/tab3. Some data needs to be fetched across all the routes so created a service for the same and return promise object. When the object gets resolved I am throwing $rootscope.emit event and listening it using $on on corresponding tabs. Since my tab1 tab2 and tab3 data is dependant on the service data, I listen to the event and then only performs the corresponding tasks.
Problem is When I click the Tab2 from tab1 page or vice versa $rootscope event gets lost and tab2 doesn't know about any such event. Am I missing something over here? I am very new to angularJS but not able to find an appropriate solution for the same. Is this because of html5 route mode or normal behaviour in routes? Please help me out.
Thanks in advance
So whats happening is child controller is not called when the event is broadcasted, so registering of $on child listener is not there. Eg: While on tab1, tab2 controller is not loaded so broadcast event which is thrown during tab1 page (even if it is thrown on rootscope) will not listen to the $on on tab2 and tab3. So loading of children listeners before parent broadcast is necessary.
So I have moved to route resolve property and this solves my case. For reference: http://odetocode.com/blogs/scott/archive/2014/05/20/using-resolve-in-angularjs-routes.aspx
In my Angular app, some routes have reloadOnSearch set to false so that Bootstrap tabs work ok.
The problem comes when a link in one of those views links to another of those views. Links just don't work, because the controller does not reload the view.
So I have to use ng-click on those links.
$scope.goToThisPage = function () {
$location.path(newPage);
$route.reload();
};
However, that does not work and always takes me to the default routing. Same happens if I replace the last line of the function with $scope.$apply().
What is the best way to move between routes that have reloadOnSearch set to false?
Do you have a separate controller for each of those tabs?
As far as I know, reloadOnSearch: false will only prevent the controller from reloading if a query parameter or hash in the url changes. So, moving between /route/page?param=1 and /route/page?param=2 will not reload the controller, but moving to /route/anotherpage definitely should.
I don't understand entirely how you're getting this issue, but for what it's worth, this is how I've solved reloadOnSearch issues when I having a single controller. Even though the controller and view don't reload when a search parameter changes, $location still does, so I would just listen to $locationChangeSuccess in the controller and make any changes to bound scope variables in the callback.
Edit
Looking at the documentation for tabs, wouldn't it be possible for you to just not use links to switch the tabs, and instead call the .tab("show") method using ng-click?
I'm struggling to handle the back button and ask confirmation to the user, if app state is dirty. Closing tab and reload is already handled via the onbeforeunload hook.
I've played with $routeChangeStart, $beforeRouteChange, etc. but can't handle it correctly.
With $routeChangeStart, the route is effectively changed before my callback is called.
What is the correct way to handle this situation?
Thanks for your help.
I believe $locationChangeStart fires when you would like it to.
you could use:
$scope.$on('$routeChangeStart', function(next, current) {
//broadcasted before a route change
// do something here
});
See more of it on : $route
Keep a model of the dirty state in a parent controller, common to all views? An alert/confirm appears if a dirty state is detected by any view's controller, with a "Cancel" button that resets $location.path(...) to the dirty page.
Basically, I am trying to check if the previous page on every route was equal to one specific page on my site. If it is, then I want to keep the person on that view, otherwise, they can proceed to the other view.
Is there a way in a Backbone.js router, to fire off a global event that will fire before the route callback is executed?
Or, is there a way to have a catch all route that does some checking then forwards to the appropriate route.
I think overridding Backbone.History.navigate and only invoking the superclass method conditionally might work. You could also add an additional event handler for window.hashChange and window.pushState events wired up before the backbone history, and prevent the default propagation of those events if your criteria match.