AngularJS与$ location.path分页,但没有ngView重新加载

我的单页应用程序加载一个主页,我想显示一系列的想法。 每个想法都显示在一个animation的闪存容器中,animation显示在这些想法之间循环。

想法被加载使用$ http:

$scope.flash = new FlashInterface scope:$scope,location:$location $http.get("/competition.json") .success (data) -> $scope.flash._init data 

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

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

我在这里调用$ apply,因为这个事件来自于AngularJS上下文,即Flash。 我想为当前的控制器/视图保持和视图不重新加载。 这是非常糟糕的,因为重新加载视图导致整个Flash对象被扔掉,并且preloader循环再次开始。

我试着听$ routeChangeStart做一个preventDefault:

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

但无济于事。 整个事情将是hunky dory,如果我可以找出重写视图重新加载当我更改$ location.path的方式。

我仍然很感激AngularJS的方式,所以我会很高兴有关如何构build应用程序来实现我的目标的任何指针!

而不是更新path,只需更新查询参数与页码。

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

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

并在您的应用更新$location

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

从这个博客文章 :

默认情况下,所有位置更改都将通过路由过程,从而更新angular度视图。

但是,有一个简单的方法来短路。 用于位置更改的angular度监视(无论是通过在地址栏中键入,单击链接或通过$location.path()设置位置来完成)。 当它感觉到这个变化时,它会广播一个事件$locationChangeSuccess ,并开始路由过程。 我们所做的就是捕捉事件并将路线重置为之前的状态。

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

我的解决scheme是使用$ routeChangeStart,因为这会给你“下一个”和“最后”的路线,你可以比较它们,而不需要额外的variables,如$ locationChangeSuccess。

好处是能够在使用“/ property / value”URL风格时next.params.yourproperty这两个“next”和“last”路由上的“params”属性,当然还可以使用$location.url$location.path来改变URL而不是$location.search() ,这取决于“?property = value”的URL风格。

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

 $scope.$on('$routeChangeStart',function(e,next,last){ if(next.$$route.controller === last.$$route.controller){ e.preventDefault(); $route.current = last.$$route; //do whatever you want in here! } }); 

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

您应该通过dependency injection加载$location并使用以下命令:

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

请记住,在使用$location.path ,不应该使用#标签。 这是为HTML5模式的兼容性。

$ locationChangeSuccess事件是一种暴力破解方法,但是我发现检查path允许我们避免在pathpath模板不变的情况下重新加载页面,但在切换到不同的路由模板时重新加载页面:

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

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

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

我需要这样做,但在尝试获取$locationChange~以获取它的function之后,我学到了你可以在使用resolveroute上做到这一点。

 $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; }] } } );