2013-08-20 6 views
76

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

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

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

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

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

+1

Если вы хотите, чтобы ваши данные, чтобы выжить изменения маршрута на стороне клиента , почему бы не надавить на услугу? – Riko

ответ

122

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

Если будет принято ответ, я создам отдельный вопрос без каких-либо вещей: «param». Просто глупый вопрос: как не перерисовать вид. –

+2

Я думаю, что [angle-ui-router] (http://angular-ui.github.io/ui-router/sample/#/contacts) станет очевидным выбором в этом случае. – codef0rmer

+1

Я использую событие '$ routeUpdate'. Я думаю, что '$ routeChangeStart' запускается при переходе в другое место. – lucassp

8

Вы можете установить для reloadOnSearch свойство $ routeProvider значение false.

Возможный дубликат вопрос: Can you change a path without reloading the controller in AngularJS?

С уважением

+0

Это похоже на дубликат. К сожалению, похоже, что у них такая же проблема, если она является частью URL-адреса, а не переменной запроса, она обновляется. –

+0

Нет, это не дублирует. –

+0

Это не дубликат, так как связанный вопрос касается не перезагрузки контроллера, и это не перезагрузка шаблона. Решение в связанном вопросе заставит просмотр перезагрузить. –

3

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

+0

Я пробовал, и он повторно отображает представления об изменении маршрута. –

+2

Вы пытались использовать '$ state.transitionTo()' вместо '$ location.path()'? – DreamSonic

+1

Я вообще не меняю $ location.path(), где следует писать '$ state.transitionTo()' then? –

0

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

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

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

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

+1

Не только $ location обновит представление. ng-include также, даже не меняя $ location. –

+0

@OZ_ Я не предлагал ngInclude, так как это просто изменение состояния внутри представления. Я просто предлагаю, вероятно, что-то вроде ng-if, которое было бы связано с функцией, которая может определить routeParams. –

2

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

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

  1. выключает $ routeProvider
  2. в контроллере MainPage добавить две див с атрибутом пользовательской директивы - каждая директива содержит только '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); 
    }; 
    

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

0

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

window.history.replaceState ('Object', 'Title', '/ нового URL');

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

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

3

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

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

В настоящее время из-за чего may be considered as a bug установка 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 
    }); 

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

-2

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

+0

. Я не понимаю, почему добавление другого ответьте здесь. – gsamaras

+1

его записку к истории. – abc

5

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

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

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

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

спасибо, работает. Но, может быть, вы не должны распространять оригинальное $ location? – rofrol

Смежные вопросы