在Angular JS中更新URL而不重新呈现视图
我正在AngularJS中构build一个仪表板系统,我遇到了通过$location.path
设置url的问题
在我们的仪表板中,我们有一些小部件。 当你点击它们时,每个都会显示一个更大的最大化视图。 我们正在尝试设置深层链接,以允许用户将最大化的小部件链接到仪表板。
目前,我们有2个看起来像/dashboard/:dashboardId
和/dashboard/:dashboardId/:maximizedWidgetId
当用户最大化一个小部件时,我们使用$location.path
更新url,但是这导致视图重新渲染。 由于我们有所有的数据,我们不想重新加载整个视图,我们只想更新URL。 有没有一种方法来设置url,而不会导致视图重新呈现?
HTML5Mode
设置为true
。
实际上,每次更改url时都会显示一个视图。 多数民众赞成$ routeProvider如何在Angular中工作,但您可以传递maximizeWidgetId
作为不重新呈现视图的查询string。
App.config(function($routeProvider) { $routeProvider.when('/dashboard/:dashboardId', {reloadOnSearch: false}); });
当你点击一个小部件来最大化:
<a href="#/dashboard/1?maximizeWidgetId=1">Maximum This Widget</a> or $location.search('maximizeWidgetId', 1);
地址栏中的url将变为http://app.com/dashboard/1?maximizeWidgetId=1
你甚至可以看到当URL中的search更改(从一个小部件到另一个小部件)
$scope.$on('$routeUpdate', function(scope, next, current) { // Minimize the current widget and maximize the new one });
您可以将$ routeProvider的reloadOnSearch属性设置为false。
可能的重复问题: 你可以改变一个path,而无需重新加载AngularJS中的控制器?
问候
对于那些需要改变完整path()没有控制器重新加载
这里是插件: https : //github.com/anglibs/angular-location-update
用法:
$location.update_path('/notes/1');
我们正在使用Angular UI 路由器而不是内置路由来处理类似的情况。 它似乎没有重新实例化控制器并重新呈现整个视图。
我意识到这是一个古老的问题,但是因为我花了一天半的时间才find答案,所以在这里。
如果使用angular-ui-router,则不需要将path转换为查询string 。
目前,由于可能被认为是一个错误 ,在状态中设置reloadOnSearch: false
将导致能够在不重新加载视图的情况下改变路由。 GitHub用户lmessinger甚至提供了一个演示。 你可以find他的评论链接上面的链接。
基本上所有你需要做的是:
- 使用
ui-router
而不是ngRoute
- 在你的状态下,用
reloadOnSearch: false
声明你想要的
在我的应用程序中,我有一个类别列表视图,从中可以使用像这样的状态到达另一个类别:
$stateProvider.state('articles.list', { url: '{categorySlug}', templateUrl: 'partials/article-list.html', controller: 'ArticleListCtrl', reloadOnSearch: false });
而已。 希望这可以帮助!
我如何实现它:
(我的解决scheme主要是当你需要改变整个路线的情况下,而不是子部分)
我有菜单(menuPage)的页面,不应该在导航上清理数据(每页都有很多input,如果数据意外消失,用户将非常非常不高兴)。
- closures$ routeProvider
-
在mainPage控制器添加两个自定义指令属性的div – 每个指令只包含“templateUrl”和“范围:真”
<div ng-show="tab=='tab_name'" data-tab_name-page></div>
-
mainPage控制器包含行来模拟路由:
if (!$scope.tab && $location.path()) { $scope.tab = $location.path().substr(1); } $scope.setTab = function(tab) { $scope.tab = tab; $location.path('/'+tab); };
就这样。 对于每个页面都有单独的指令有点难看,但是在指令中使用dynamic的templateUrl(作为函数)会引发页面的重新渲染(并且丢失input的数据)。
如果我理解你的问题,你想,
- 当用户在/仪表板/:dashboardId时,最大化该小部件,并使该小部件最大化。
- 您希望用户有能力回到/ dashboard /:dashboardId /:maximizedWidgetId,并仍然看到最大化的小部件。
您只能configurationrouterConfig中的第一个路由,并使用RouteParams来确定最大化的小部件是否在此configuration路由的控制器中的参数中传递,并最大化作为parameter passing的参数。 如果用户第一次使其最大化,请使用UI上的maximizedWidgetId将url分享到此最大化视图。
只要你使用$ location(这只是本地位置对象的包装)来更新path,它将刷新视图。
我有一个想法使用
window.history.replaceState('Object','Title','/ new-url');
如果你这样做,消化周期发生,它将完全破坏事情。 但是,如果您将其设置回正确的URL,angular度期望它是好的。 所以理论上你可以存储angular度期望的正确url,并在知道摘要之前重置它。
我还没有testing过这个。
下面的代码可以让你改变url而不用redirect,例如: http:// localhost /#/ 691?foo?bar?blabla
for(var i=0;i<=1000;i++) $routeProvider.when('/'+i, {templateUrl: "tabPages/"+i+".html",reloadOnSearch: false});
但是当你改变为http:// localhost /#/ 692时 ,你将被redirect。