AngularJS使用$ location.path进行分页但没有重新加载ngView

时间:2012-09-14 10:23:20

标签: angularjs

我的单页应用程序加载主页,我想显示一系列想法。每个想法都显示在一个动画flash容器中,动画显示在想法之间循环。

使用$ http:

加载提示
$scope.flash = new FlashInterface scope:$scope,location:$location

$http.get("/competition.json")
  .success (data) ->
    $scope.flash._init data

但是,要从历史导航和UX中受益,我希望更新地址栏,以便使用$ location显示每个想法的正确网址:

$location.path "/i/#{idea.code}"
$scope.$apply()

我在这里调用$ apply,因为此事件来自AngularJS上下文,即Flash。我希望保留当前的控制器/视图,并使视图不重新加载。这非常糟糕,因为重新加载视图会导致整个flash对象被抛弃并且预加载器循环再次开始。

我试过听$ routeChangeStart做一个preventDefault:

$scope.$on "$routeChangeStart", (ev,next,current) ->
  ev.preventDefault()
$scope.$on "$routeChangeSuccess", (ev,current) ->
  ev.preventDefault()

但无济于事。如果我在改变$ location.path时想出一种覆盖视图重载的方法,整个事情就会变得很糟糕。

我仍然非常感觉AngularJS,所以我很高兴有关如何构建应用程序以实现我的目标的任何指示!

7 个答案:

答案 0 :(得分:92)

只需使用页码更新查询参数,而不是更新路径。

设置您的路由以忽略查询参数更改:

....
$routeProvider.when('/foo', {..., reloadOnSearch: false})
....

并在您的应用中使用以下内容更新$location

...
$location.search('page', pageNumber);
...

答案 1 :(得分:31)

来自this blog post

  

默认情况下,所有位置更改都会经过路由流程   更新角度视图。

     

然而,有一种简单的方法可以将其短路。角度表   改变位置(是否通过键入来完成)   位置栏,单击链接或设置位置   $location.path())。当它感觉到这种变化时,它会广播一个   事件$locationChangeSuccess,并开始路由过程。什么   我们做的是捕获事件并将路径重置为原来的路线   先前。

function MyCtrl($route, $scope) {
    var lastRoute = $route.current;
    $scope.$on('$locationChangeSuccess', function(event) {
        $route.current = lastRoute;
    });
}

答案 2 :(得分:3)

我的解决方案是使用$ routeChangeStart,因为它为您提供了“next”和“last”路由,您可以比较它们,而无需像$ locationChangeSuccess那样需要额外的变量。

当您使用“/ property / value”URL样式时,当前使用{{next.params.yourproperty时,可以访问“next”和“last”路由中的“params”属性。 1}}或$location.url更改网址,而不是取决于“?property = value”网址格式的$location.path

在我的情况下,我不仅使用它,而且还防止路径改变是控制器没有改变:

$location.search()

就个人而言,我觉得AngularJS应该提供一种控制它的方法,现在他们假设每当你改变浏览器的位置时你想改变路线。

答案 3 :(得分:1)

您应该通过依赖注入加载$location并使用以下内容:

$scope.apply(function () {
    $location.path("yourPath");
}

请注意,在使用$location.path时,您应使用主题标签(#)。这是为了兼容HTML5模式。

答案 4 :(得分:0)

$ locationChangeSuccess事件是一种蛮力方法,但我发现检查路径允许我们在路径路径模板未更改时避免页面重新加载,但在切换时重新加载页面到不同的路线模板:

var lastRoute = $route.current;
$scope.$on('$locationChangeSuccess', function (event) {
    if (lastRoute.$$route.originalPath === $route.current.$$route.originalPath) {
        $route.current = lastRoute;
    }
});

将该代码添加到特定控制器会使重新加载更加智能化。

编辑:虽然这使它更容易一些,但我最终并不喜欢我编写的代码的复杂性,以保持友好的URL。最后,我只是切换到一个搜索参数,角度处理得更好。

答案 5 :(得分:0)

我需要这样做,但在试图让$locationChange~事件让它发挥作用之后,我了解到你可以使用resolveroute上实际执行此操作。< / p>

$routeProvider.when(
    '/page',
    {
        templateUrl : 'partial.html',
        controller : 'PageCtrl',
        resolve : {
            load : ['$q', function($q) {
                var defer = $q.defer();

                if (/*you only changed the idea thingo*/)
                    //dont reload the view
                    defer.reject('');
                //otherwise, load the view
                else
                    defer.resolve();

                return defer.promise;
            }]
        }
    }
);

答案 6 :(得分:0)

使用AngularJS V1.7.1$route添加了对reloadOnUrl配置选项的支持。

如果路由/foo/:id设置了reloadOnUrl = false,那么从/foo/id1移到/foo/id2只会广播$routeUpdate事件,并且会不要重新加载视图并重新实例化控制器。