AngularJS redirect without pushing a history state

后端 未结 2 1107
北海茫月
北海茫月 2020-12-14 06:14

I\'m working on an AngularJS app that has a catch all route (eg, .when(\'/:slug\', {...)) which is necessary to support legacy url formats from a previous (non-

相关标签:
2条回答
  • 2020-12-14 06:43

    The normal operation of the route system is for the $route service to watch for the $locationChangeSuccess event and then begin loading a route. When it's done loading the template, performing the resolve steps and instantiating the controller it then in turn broadcasts a $routeChangeSuccess event. That $routeChangeSuccess is monitored by the ng-view directive, and that's how it knows to swap out the templates and scopes once the new route is ready.

    With all of the above said, it may work to have application code emulate the behavior of the $route service by updating the current route and emitting the route change event to get the view to update:

    var errorRoute = $route.routes[null]; // assuming the "otherwise" route is the 404
    // a route instance is an object that inherits from the route and adds
    // new properties representing the routeParams and locals.
    var errorRouteInstance = angular.inherit(
        errorRoute,
        {
            params: {},
            pathParams: {},
        }
    );
    // The $route service depends on this being set so it can recover the route
    // for a given route instance.
    errorRouteInstance.$$route = errorRoute;
    
    var last = $route.current;
    $route.current = errorRouteInstance;
    
    // the ng-view code doesn't actually care about the parameters here,
    // since it goes straight to $route.current, but we should include
    // them anyway since other code might be listening for this event
    // and depending on these params to behave as documented.
    $rootScope.broadcast('$routeChangeSuccess', errorRoute, last);
    

    The above assumes that your "otherwise" route doesn't have any "resolve" steps. It also assumes that it doesn't expect any $routeParams, which is of course true for the "otherwise" route but might not be true if you use a different route.

    It's unclear what of the above is depending on implementation details vs. interface. The $routeChangeSuccess event is certainly documented, but the $$route property of the route instance seems to be an implementation detail of the route system given its double-dollar-sign name. The detail that the "otherwise" route is kept in the route table with the key null is possibly also an implementation detail. So with all of this said, this behavior may not remain functional in future versions of AngularJS.

    For more information you could refer to the ng-view code that handles this event, which is ultimately what the above code is trying to please, along with the event emitting code that I used as the basis for the above example. As you could infer from these links, the information in this post is derived from the latest master branch of AngularJS, which at the time of writing is labelled as 1.2.0-snapshot.

    0 讨论(0)
  • 2020-12-14 06:51

    You can change the url without adding to the history state, found here under "Replace Method". This is effectively the same as calling HTML5's history.replaceState().

    $location.path('/someNewPath').replace();
    

    I haven't found that it's possible to change the view without changing the url. The only method to change the view, that I've found, is to change the location path.

    0 讨论(0)
提交回复
热议问题