0

I am using angular ui-router. In some cases in my application I open popups without changing the url. I want to be able to close this popup when clicking the browser back button - on mobile.

Is there a way to do it with (or without) ui-router?

EDIT:

A more specific explanation: I have a menu which is a popup and it can be opened all the time. I want this menu to be closed with browser back button on mobile. If I change the url when opening the menu everything should work. BUT is there a way to define a state that adds a suffix to current url?

For example if I have two urls:

  1. myapp/page1
  2. myapp/page2

Then opening the menu will switch to "menu" state which will change the url to either:

  1. myapp/page1/menu
  2. myapp/page2/menu

If this is not possible then I would like to open the menu without changing the url and still be able to close the menu with the browser back button.

julius_am
  • 1,422
  • 2
  • 23
  • 42
  • can you share you code in a jsfiddle ? – MayK Nov 17 '15 at 13:59
  • 1
    You can't intercept a 'back' button event. But you can create a *fake* route on the navigation history stack. See http://stackoverflow.com/questions/1844491/intercepting-call-to-the-back-button-in-my-ajax-application-i-dont-want-it-to – Michael Nov 17 '15 at 14:06

1 Answers1

0

Regarding the first part of your question, I don't know of a way make a state a child of another state dynamically. A workaround I've used is to explicitly define all the child states in the config blocks as normal but re-use the same template/controller. Of course, that only works if you know all potential child states in advance.

As for back button detection, you can listen for $locationChangeStart and $stateChangeStart. When the state is changed internally, $stateChangeStart is fired first and then a location change is triggered. When the state is changed externally (by the back button, for example), $locationChangeStart happens first. Here's an example of how to leverage that:

var state = $state.current.name;
var location = $location.absUrl();

var stateChangingExternally = false;
var stateChangingInternally = false;

var offLocationChangeStartEvt = $scope.$on('$locationChangeStart', function(evt, to, from) {
  if (from === location) {
    stateChangingExternally = !stateChangingInternally;
    offLocationChangeStartEvt();
  }
});

var offStateChangeStartEvt = $scope.$on('$stateChangeStart', function(evt, to, toParams, from) {
  if (from.name === state) {
    stateChangingInternally = !stateChangingExternally;
    if (stateChangingExternally) {
      evt.preventDefault();
      // do whatever here
    }
    offStateChangeStartEvt();
  }
});
derrik
  • 122
  • 1
  • 7