我需要在加载特定视图时确定以前的路由.
这就是我做到的
app.controller('TrashCtrl',function($scope,$rootScope){ $rootScope.$on('$locationChangeSuccess',function(evt,absNewUrl,absOldUrl) { var hashIndex = absOldUrl.indexOf('#'); var oldRoute = absOldUrl.substr(hashIndex + 2); console.log(oldRoute); }); });
不幸的是,在逻辑开始工作之前,我必须调用与该控制器对应的视图.控制器第一次触发时,不记录任何内容.此外,在此初始加载后,应用程序将记录每个routeChange,即使加载的视图不能与TrashCtrl一起使用
我希望这样:
>当加载视图Trash(其控制器为TrashCtrl)时,我需要先前的路由或空字符串(如果这是第一个).
>如果仅在调用实际的垃圾路径时触发,而不是在每个路径更改时触发,那将是很好的.
如何实现这一目标?
编辑:
请注意,我知道可以创建自定义服务并将每个更改写入其中.这不是我想要的.我想仅在需要时才对数据进行处理,例如在调用Trash时.
解决方法
$routeProvider
的resolve属性中的前一个路径的路径.
>仅当加载/ trash视图时(不是针对每个路径),它才会检测上一个路径.
>它不需要知道其他路线的任何信息.
>添加其他路由时无需额外配置(这会增加实现复杂性,但会简化维护).
用语言说
以下是“简单”字样的工作原理:
在resolve对象中,它为下一个$routeChangeSuccess事件注册一个侦听器.
捕获事件后,它会取消注册侦听器.
一旦侦听器未注册,它就会解析具有前一路径路径值的promise.
注入trashCtrl的对象(来自resolve属性)是一个返回上述promise的函数.
控制器接收该函数,调用它来获取承诺并等待承诺通过前一个路径的路径得到解决.
简单就像馅饼!
注意:
为了“简单”,我没有考虑导致$routeChangeError(而不是$routeChangeSuccess)的错误的可能性.一个人应该考虑到这一点并取消注册听众,但即使你不这样做,也不会有任何伤害 – 听众会在$routeChangeSuccess被触发一次之前离开.
控制器:
app.controller('trashCtrl',function ($scope,prevRoutePromiseGetter) { prevRoutePromiseGetter().then(function (prevRoute) { $scope.prevRoute = prevRoute || 'nowhere'; }); });
解决对象:
resolve: { prevRoutePromiseGetter: function ($q,$rootScope) { var deferred = $q.defer(); var dereg = $rootScope.$on('$routeChangeSuccess',next,prev) { dereg(); deferred.resolve((prev.originalPath || '').substr(1)); } ); return function () { return deferred.promise; }; } }
另见,这是short demo.