我正在开发一个AngularJS应用程序,该应用程序具有捕获所有路径(例如,.when('/:slug', {...)
),这是支持应用程序的先前(非角度)版本的遗留URL格式所必需的。响应catch的控制器尝试拉动相关对象,如果没有找到,则使用$location.path
方法重定向到404页面。这有助于将用户带到404页面,但是当用户在浏览器中回击时,它会将他们带回到首先强制他们进入404页面的页面,他们最终无法逃脱循环。 / p>
我的问题是,是否存在1)处理这种情况的更好模式,或2)是否有办法重新路由不会在浏览器中强制执行历史推送状态的用户?
答案 0 :(得分:56)
您可以在不添加历史记录状态的情况下更改网址,在“替换方法”下找到here。这实际上与调用HTML5的history.replaceState()。
相同$location.path('/someNewPath').replace();
我没有发现可以在不更改网址的情况下更改视图。我发现,改变视图的唯一方法是更改位置路径。
答案 1 :(得分:3)
路由系统的正常操作是$route
服务监视$locationChangeSuccess
事件,然后开始加载路由。当它完成加载模板,执行解析步骤并实例化控制器后,它接着广播$routeChangeSuccess
事件。 $routeChangeSuccess
指令监视ng-view
,并且一旦新路由准备好,它就知道如何交换模板和范围。
综上所述,通过更新当前路由并发出路由更改事件以使视图更新,应用程序代码可以模拟$route
服务的行为。
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);
以上假设您的“其他”路线没有任何“解决”步骤。它还假设它不期望任何$routeParams
,这对于“其他”路线当然是正确的,但如果您使用不同的路线则可能不是。
目前还不清楚上述内容取决于实现细节与界面。 $routeChangeSuccess
事件肯定是记录在案的,但路由实例的$$route
属性似乎是路由系统的实现细节,给出了双美元符号名称。使用键null
在路由表中保留“其他”路由的详细信息也可能是实现细节。所有这些都说明了,这种行为在AngularJS的未来版本中可能无法保持功能。
有关详情,请参阅the ng-view
code that handles this event,这是上述代码最终要求的内容,以及我用作上述示例基础的the event emitting code。正如您可以从这些链接推断的那样,这篇文章中的信息来自AngularJS的最新主分支,在撰写本文时,它被标记为1.2.0快照。