3

正如大多数 Angular 开发人员所知,Resolve属性允许保护对某些页面的访问。

这里是代码片段的简短示例:

.config(['$routeProvider', 'securityAuthorizationProvider',
                function ($routeProvider, securityAuthorizationProvider) {
                      $routeProvider.when('/test', {
                          templateUrl: '/myCorrespondingView.tpl.html',
                          controller: 'MyCorrespondingCtrl',
                          resolve: securityAuthorizationProvider.requireAuthenticatedUser
                      });
                }])

假设一个页面包含一个名为“单击此处访问受保护页面”的链接($location.path("/test")在后台创建一个)。

期望是:当我单击它时,将resolve其设置为rejected并且...不要重定向到调用者页面以外的任何其他页面。

这会导致...什么都没有(用户无法访问页面这一简单事实就足够了),但 URL 更改为目标受保护页面。=> myApp.com/test (为什么 Angular 只有在成功的承诺结果的情况下才进行此替换??:(,但这是我刚刚问过的另一个问题:AngularJS / 仅在解决相应模板的解析属性时才更改 URL) .

然后……再次点击……

遗骸似乎resolve根本没有再处理。

然后...单击应用程序上的其他链接(当然没有完全重定向),无论您想要更改 URL,然后重新单击受保护的链接 =>Resolve将再次得到很好的处理。

是否有 Angular 机制检查当前页面 URL 和所需页面 URL,resolve如果两者相同,则避免重新处理任务?

resolve即使 URL 已经对应于目标页面一,我也真的想强制执行该过程。

**更新********来自这篇文章:https ://stackoverflow.com/a/12429133/985949

Angular 监视位置变化(无论是通过在位置栏中键入、单击链接还是通过 $location.path() 设置位置来完成)。当它感知到这个变化时,它会广播一个事件“$locationChangeSuccess”,并开始路由过程。

听起来我上面假设的检查确实是通过$location.path方法完成的……如果可以强制进行评估,那就太好了。

4

2 回答 2

3

Angular 路由响应 URL 的变化,而不是点击。如果浏览器中的位置没有改变,角度根本不会拾取它。

看来您应该做的是创建一个服务来侦听“$locationChangeSuccess”并跟踪最后一条成功的路线。然后在 $routeChangeError 上设置另一个侦听器,将位置重置为失败时的最后一条成功路由。这将防止您处于位置与当前活动路线不匹配的不一致状态。

一旦你这样做了,再次点击链接会导致浏览器再次尝试更改位置,从而再次触发你的解析。

于 2013-10-30T00:41:13.313 回答
0

我发现这篇文章确认了上面@dtabuenc 的解决方案。这是我的:

angular.module('services.locationChanger', [])
    .service('locationChanger', ['$location', '$route', '$rootScope', function ($location, $route, $rootScope) {

        this.skipReload = function () {
            var lastRoute = $route.current;
            $rootScope.$on('$locationChangeSuccess', function () {
                $route.current = lastRoute;
            });
            return this;
        };

        this.withoutRefresh = function (url, doesReplace) {
            if(doesReplace){
                $location.path(url).replace();
            }
            else {
                $location.path(url || '/');
            }
        };
    }]); 

resolve并且流程部分中的任何调用者都是:

locationChanger.skipReload().withoutRefresh("/", true);

奇迹般有效。

于 2013-10-30T01:34:00.563 回答