80

我正在 AngularJS 中构建仪表板系统,但在设置 url 时遇到了问题$location.path

在我们的仪表板中,我们有一堆小部件。当您单击它时,每个都会显示一个更大的最大化视图。我们正在尝试设置深度链接,以允许用户链接到具有最大化小部件的仪表板。

/dashboard/:dashboardId目前,我们有 2 条路线看起来像/dashboard/:dashboardId/:maximizedWidgetId

当用户最大化一个小部件时,我们使用 更新 url $location.path,但这会导致视图重新呈现。由于我们拥有所有数据,我们不想重新加载整个视图,我们只想更新 URL。有没有办法设置 url 而不会导致视图重新呈现?

HTML5Mode设置为true

4

9 回答 9

133

实际上,每次更改 url 时都会呈现一个视图。这就是 $routeProvider 在 Angular 中的工作方式,但您可以maximizeWidgetId作为不重新渲染视图的查询字符串传递。

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 中的搜索更改(从一个小部件到另一个小部件)

$scope.$on('$routeUpdate', function(scope, next, current) {
   // Minimize the current widget and maximize the new one
});
于 2013-08-31T18:32:39.037 回答
9

您可以将 $routeProvider 的 reloadOnSearch 属性设置为 false。

可能的重复问题:您可以在不重新加载 AngularJS 中的控制器的情况下更改路径吗?

问候

于 2013-08-20T14:44:12.067 回答
6

对于那些需要在没有控制器重新加载的情况下更改完整路径()的人

这是插件:https ://github.com/anglibs/angular-location-update

用法:

$location.update_path('/notes/1');
于 2015-08-12T11:36:24.193 回答
3

对于类似的场景,我们使用 Angular UI Router而不是内置路由。它似乎没有重新实例化控制器并重新渲染整个视图。

于 2013-08-31T18:08:13.863 回答
3

我意识到这是一个老问题,但是由于我花了一天半的时间才找到答案,所以就这样吧。

如果您使用angular-ui-router ,则无需将路径转换为查询字符串

目前,由于可能被视为错误,设置reloadOnSearch: false状态将导致能够在不重新加载视图的情况下更改路线。GitHub 用户 lmessinger 甚至提供了一个演示。您可以从上面链接的他的评论中找到链接。

基本上你需要做的就是:

  1. 使用ui-router代替ngRoute
  2. 在您的州,声明您希望与 reloadOnSearch: false

在我的应用程序中,我有一个类别列表视图,您可以从该视图中使用如下状态进入另一个类别:

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

就是这样。希望这可以帮助!

于 2014-04-04T12:49:16.427 回答
2

我是如何实现它的:(
我的解决方案主要用于您需要更改整个路线而不是子部分的情况)

我有带有菜单(menuPage)的页面,并且不应该在导航时清理数据(每个页面上有很多输入,如果数据意外消失,用户会非常非常不高兴)。

  1. 关闭 $routeProvider
  2. 在 mainPage 控制器中添加两个具有自定义指令属性的 div - 每个指令仅包含 'templateUrl' 和 'scope: true'

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

就这样。每个页面都有单独的指令有点难看,但是在指令中使用动态 templateUrl(作为函数)会引发页面的重新渲染(并丢失输入数据)。

于 2013-09-04T13:04:29.347 回答
0

如果我理解你的问题是正确的,你想,

  1. 当用户在 /dashboard/:dashboardId 上时最大化小部件并且他最大化小部件。
  2. 您希望用户能够返回到 /dashboard/:dashboardId/:maximizedWidgetId 并且仍然看到小部件最大化。

您可以仅在 routerConfig 中配置第一个路由,并使用RouteParams来识别是否在此配置路由的控制器中的参数中传递了最大化的小部件,并最大化作为参数传递的那个。如果用户是第一次将其最大化,请在 UI 上将这个最大化视图的 url 共享给最大化的WidgetId。

只要您使用 $location(它只是本地位置对象的包装器)来更新路径,它就会刷新视图。

于 2013-08-31T19:37:30.617 回答
0

我有一个想法

window.history.replaceState('对象', '标题', '/new-url');

如果您这样做并且发生消化循环,它将完全破坏事情。但是,如果您将其设置回 angular 期望的正确 url,就可以了。因此,理论上您可以存储 angular 期望的正确 url,并在您知道摘要触发之前将其重置。

我还没有测试过这个。

于 2014-02-21T16:42:46.667 回答
-3

下面的代码将允许您更改 url 而无需重定向,例如: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时,您将被重定向。

于 2015-01-25T21:33:04.793 回答