Обновление URL-адреса в Angular JS без просмотра ре-рендеринга

Я создаю систему приборной панели в AngularJS, и у меня возникает проблема с настройкой url через $location.path

В нашей информационной панели есть куча виджетов. Каждый из них показывает увеличенное максимальное изображение, когда вы нажимаете на него. Мы пытаемся настроить глубокую привязку, чтобы пользователи могли ссылаться на личную панель с максимальным виджетами.

В настоящее время у нас есть 2 маршрута, которые выглядят как /dashboard/:dashboardId и /dashboard/:dashboardId/:maximizedWidgetId

Когда пользователь максимизирует виджет, мы обновляем URL-адрес с помощью $location.path, но это вызывает повторную визуализацию представления. Поскольку у нас есть все данные, мы не хотим перезагружать весь вид, мы просто хотим обновить URL. Есть ли способ установить URL-адрес, не вызывая повторную визуализацию?

HTML5Mode установлен на true.

Ответ 1

Фактически, представление будет отображаться каждый раз при изменении 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
});

Ответ 3

Для тех, кто нуждается в изменении полного пути() без перезагрузки контроллеров

Вот плагин: https://github.com/anglibs/angular-location-update

Использование:

$location.update_path('/notes/1');

Ответ 4

Мы используем Angular UI Router вместо встроенных маршрутов для аналогичного сценария. Кажется, он не повторяет создание контроллера и повторное отображение всего представления.

Ответ 5

Я понимаю, что это старый вопрос, но так как мне потребовался хороший день и полтора, чтобы найти ответ, так и здесь.

Вам не нужно преобразовывать свой путь в строки запроса, если вы используете angular -ui-router.

В настоящее время из-за того, что может считаться ошибкой, установка reloadOnSearch: false в состоянии приведет к возможности изменения маршрута без перезагрузки представления. Пользователь GitHub lmessinger был достаточно доволен, чтобы предоставить ему демо-версию. Вы можете найти ссылку на свой комментарий, связанный выше.

В основном все, что вам нужно сделать, это:

  • Используйте ui-router вместо ngRoute
  • В ваших состояниях объявите те, которые вы хотите, с помощью reloadOnSearch: false

В моем приложении у меня есть список категорий, из которого вы можете перейти в другую категорию, используя такое состояние:

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

Что это. Надеюсь, это поможет!

Ответ 6

Как я его реализовал:
(мое решение в основном для случаев, когда вам нужно изменить весь маршрут, а не на части)

У меня есть страница с меню (menuPage), и данные не должны быть очищены при навигации (на каждой странице есть много входов, и пользователь будет очень огорчен, если данные случайно исчезнут).

  • отключить $routeProvider
  • в mainPage-контроллере добавьте два div с настраиваемым атрибутом директивы - каждая директива содержит только "templateUrl" и "scope: true"

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

Это все. Немного уродливый, чтобы иметь отдельную директиву для каждой страницы, но использование динамической функции templateUrl (как функции) в директиве провоцирует повторный рендеринг страницы (и потери данных входов).

Ответ 7

Если я правильно понял ваш вопрос, вы хотите,

  • Максимизируйте виджет, когда пользователь включен /dashboard/: dashboardId, и он максимизирует виджет.
  • Вы хотите, чтобы у пользователя появилась возможность вернуться к /dashboard/: dashboardId/: maximizedWidgetId и по-прежнему видеть, что виджет максимизирован.

Вы можете настроить только первый маршрут в routerConfig и использовать RouteParams, чтобы определить, прошел ли максимизированный виджет в параметрах в контроллер этого сконфигурированного маршрута и максимизировать значение, которое передается как параметр. Если пользователь максимизирует его в первый раз, поделитесь URL с этим максимальным представлением с помощью maximizedWidgetId в пользовательском интерфейсе.

До тех пор, пока вы используете $location (который является только оболочкой над объектом локального местоположения), чтобы обновить путь, он обновит представление.

Ответ 8

У меня есть идея использовать

window.history.replaceState('Object', 'Title', '/new-url');

Если вы это сделаете, и цикл дайджеста случится, он полностью уничтожит все. Однако, если вы вернетесь к правильному URL-адресу, который angular ожидает его одобрения. Поэтому теоретически вы можете сохранить правильный URL-адрес, который angular ожидает, и reset он перед тем, как вы узнаете, что дайджест срабатывает.

Я не тестировал это, хотя.

Ответ 9

Ниже код позволит вам изменить 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, вы будете перенаправлены.