在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他的评论链接上面的链接。

基本上所有你需要做的是:

  1. 使用ui-router而不是ngRoute
  2. 在你的状态下,用reloadOnSearch: false声明你想要的

在我的应用程序中,我有一个类别列表视图,从中可以使用像这样的状态到达另一个类别:

 $stateProvider.state('articles.list', { url: '{categorySlug}', templateUrl: 'partials/article-list.html', controller: 'ArticleListCtrl', reloadOnSearch: false }); 

而已。 希望这可以帮助!

我如何实现它:
(我的解决scheme主要是当你需要改变整个路线的情况下,而不是子部分)

我有菜单(menuPage)的页面,不应该在导航上清理数据(每页都有很多input,如果数据意外消失,用户将非常非常不高兴)。

  1. closures$ routeProvider
  2. 在mainPage控制器添加两个自定义指令属性的div – 每个指令只包含“templateUrl”和“范围:真”

      <div ng-show="tab=='tab_name'" data-tab_name-page></div> 
  3. 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的数据)。

如果我理解你的问题,你想,

  1. 当用户在/仪表板/:dashboardId时,最大化该小部件,并使该小部件最大化。
  2. 您希望用户有能力回到/ 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。