【问题标题】:AngularJS - Get previous route when firing controllerAngularJS - 触发控制器时获取先前的路线
【发布时间】:2014-05-27 12:53:24
【问题描述】:

Angular 的内部结构再次让我感到困惑。

我需要在加载特定视图时确定之前的路线。

我就是这样做的

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 路由被调用时触发,而不是在每次路由更改时触发,那就太好了。

如何实现这一目标?

编辑:

请注意,我知道创建自定义服务并将每次更改写入它的可能性。这不是我想要的。我想仅在需要时才对数据进行 fecth,例如仅在调用 Trash 时。

【问题讨论】:

  • 您是否尝试只使用$scope 而不是$rootScope?
  • @callmekatootie 是的。结果相同
  • 既然你提到了“获取数据”,你知道$routeProvider route-objects 的resolve 属性吗?
  • 虽然我指的是“数据”的 URL,但这实际上是一个不错的主意。我试试,谢谢
  • 无法理解您的用例。你可以为此创建一个 plnker 吗?

标签: angularjs routes


【解决方案1】:

我尽我所能,但似乎没有直接的方法可以访问 $routeProvider 的 resolve 属性内的前一个路由路径。

只是为了好玩,我实现了一个具有以下属性的(非常复杂的)解决方案:

  • 仅当 /trash 视图已加载时才会检测到先前的路线(并非针对每条路线)。
  • 它不必知道其余路线的任何信息。
  • 添加额外路由时无需额外配置(这增加了实现复杂性,但简化了维护)。

言辞

用“简单”的话来说它是这样工作的:

在resolve 对象中,它为下一个$routeChangeSuccess 事件注册一个监听器。
捕获事件后,它会取消注册侦听器。
一旦监听器被取消注册,它就会使用前一个路由路径的值来解析一个 promise。 注入trashCtrl(来自resolve 属性)的对象是一个函数,它返回上述承诺。
控制器接收该函数,调用它以获取承诺,并等待承诺通过前一个路由的路径得到解决。

简单到不行!

注意: 为了“简单”,我没有考虑导致$routeChangeError(而不是$routeChangeSuccess)的错误的可能性。可能应该考虑到这一点并注销侦听器,但即使您不这样做,也不会造成任何伤害 - 侦听器将继续运行,直到 $routeChangeSuccess 被触发一次。


代码

控制器:

app.controller('trashCtrl', function ($scope, prevRoutePromiseGetter) {
    prevRoutePromiseGetter().then(function (prevRoute) {
        $scope.prevRoute = prevRoute || 'nowhere';
    });
});

resolve 对象:

resolve: {
    prevRoutePromiseGetter: function ($q, $rootScope) {
        var deferred = $q.defer();
        var dereg = $rootScope.$on('$routeChangeSuccess', 
            function(evt, next, prev) {
                dereg();
                deferred.resolve((prev.originalPath || '').substr(1));
            }
        );
        return function () {
            return deferred.promise;
        };
    }
}

另请参阅此short demo。

【讨论】:

  • 这样的答案是我喜欢这个网站的原因。非常感谢您的努力!我为一个简单的服务拍摄,但很高兴看到这个解决方案。
  • 我刚刚意识到我从未链接到实际的演示(只是一个文档页面)。固定:)
  • ExpertSystem,非常感谢您!
  • 几乎完美,但我得到了/company/edit/:id?,而不是得到完整的网址......带有那个ID。
  • @sylouuu: 嗯...我想你可以在 resolve 函数中获取路由参数(使用$routeParams)。
【解决方案2】:

您需要使用 $routeChangeStart 而不是位置更改。

$rootScope.$on('$routeChangeStart', function(event, next, current) {

});

【讨论】:

  • 第一次调用视图时也不会触发
猜你喜欢
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多