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之后,我学到了你可以在使用resolve
的route
上做到这一点。
$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; }] } } );