Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse location on cancel #14

Open
jeme opened this issue May 3, 2013 · 2 comments
Open

Reverse location on cancel #14

jeme opened this issue May 3, 2013 · 2 comments
Milestone

Comments

@jeme
Copy link
Contributor

jeme commented May 3, 2013

Currently when we cancel a transition from one state to another, the location isn't updated.

This should be straight forward for when the source state has a route associated with it, however in the case where it doesn't this becomes a bit more complex, as we need to reset the route to something that should actually not cause for an activation of a state.

Until we figure that out, we should only revert when the source state has a route.

Side note, the router may be the one providing what we need for resetting the location back by a replace method that would change the current route before it changes location, so that when the route gets a location changed event, that is ignored as it is already at that route.

A mode difficult aspect of all this is the browser history, for browsers that support the new History API, we should be ok, how we handle browsers that don't will be more tricky, if not just straight out impossible (meaning that we can't get around the extra history entry it will generate).

@jeme jeme modified the milestones: v0.7.0, 0.6.3 Apr 22, 2014
@edyburn
Copy link

edyburn commented Jul 7, 2014

In order to work around this issue, we are currently doing something similar to the following:

stateTransitionProvider
  .onExit('*', {
    between: ['$from', '$view', '$q', '$state', '$location', 'checkViews',
      function() {
        return checkViews(views.pending()) // checkViews returns a promise
          .catch(function(reason) {
            $location.url($state.url($from.$fullname, $from.$params.$all));
            return $q.reject(reason);
          });
      }]
  })

However, with this solution, cancelling going forward after clicking a link adds two entries in the browser history, and cancelling jumping back (via back button dropdown) removes the skipped and all forward entries.

Unfortunately, the History API does not directly expose the relative position of the previous state, which is necessary to return to it using history.go(). An approach similar to that used by History.js seems promising:

  • Store a unique id for states when calling history.pushState()
  • Use an array of these unique ids to keep a duplicate history (splicing out forward states when the history forks)
  • Store a copy of the duplicate history in sessionStorage to persist across page reloads
  • Then, the relative indexes of the previous and current states could be found in the duplicate history to determine the delta for history.go()

@jeme
Copy link
Contributor Author

jeme commented Jul 8, 2014

@edyburn Thanks for the input.

$location.url($state.url($from.$fullname, $from.$params.$all)).replace(); should mitigate your double history entry on forward, but on the flip-side I can't really rationalize on what it will do in case of back (it's morning here and I haven't had my coffee yet).

There is some concerns/considerations around handling route-less states, which is why I have pushed this in front of me.

But in long term integrating to the History API certainly sounds interesting, (and possibly allow for optionally including History.js, similar to jQuery being optional) certainly sounds like an interesting idea.

This could make way for a $stateHistory service as well maybe, which I know has been requested by some in the UI-Router project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants