Задайте параметры запроса URL без изменения состояния с помощью Angular ui-router

Как мне обновить URL-адрес адресной строки с помощью изменяющегося параметра запроса, используя AnglerJS 'ui-router для поддержания состояния при обновлении страницы?

В настоящее время я использую $state.transitionTo('search', {q: 'updated search term'}), когда вводятся изменения, но проблема в том, что это перезагружает контроллер, перерисовывает окно и теряет фокус ввода текста.

Есть ли способ обновить stateParams и синхронизировать его с URL-адресом окна?

Ответ 1

У меня были проблемы с .transitionTo, пока я не обновился до ui-router 0.2.14. 0.2.14 правильно изменяет расположение панели (без перезагрузки контроллера) с помощью вызова типа:

$state.transitionTo('search', {q: 'updated search term'}, { notify: false });

Ответ 2

edit: играется с этим еще сегодня и поняла, что angular ui-router имеет аналогичный вариант, как родной routerProvider: "reloadOnSearch".

https://github.com/angular-ui/ui-router/wiki/Quick-Reference#options-1

По умолчанию он установлен на true, но если вы установите его в false в своем состоянии, тогда изменение состояния не произойдет, когда параметры запроса будут изменены. Затем вы можете вызвать $location.search(params); или $location.search('param', value);, и URL-адрес изменится, но ui-router не будет повторно строить весь контроллер/представление. Возможно, вам также потребуется прослушать событие $locationChangeStart в корневой области, чтобы обрабатывать назад и пересылать действия истории в вашем приложении, так как они также не будут вызывать изменения состояния.

Я также слушаю событие $stateChangeSuccess в области моего контроллера, чтобы зафиксировать начальную загрузку страницы/маршрута.

Существует некоторое обсуждение github для использования этой функции с изменениями пути (а не только изменениями URL): https://github.com/angular-ui/ui-router/issues/125, но я не тестировал это вообще с мой вариант использования был специфичен для параметров строки запроса.

В предыдущей версии моего ответа упоминалась эта проблема github:

https://github.com/angular-ui/ui-router/issues/562

Но это немного отдельная проблема, в частности, демонстрирующая модальность одного состояния над другим состоянием без изменения немодального состояния. Я пробовал исправление в этой проблеме, но он ясно, что он не предназначен для предотвращения перезагрузки всего штата при изменении URL.

Ответ 3

Обновление от 19 мая 2015 г.

Как и в ui-router 0.2.15, проблема перезагрузки состояния при изменении параметров запроса была решена. Однако новое обновление нарушило возможности API назад и вперед API с параметрами запроса. Я не смог найти обходное решение для этого.

Оригинал

Ответ на ответ не помог мне, и не было тонны других ответов. Попытка прослушать $locationChangeStart вызвала проблемы при попытке вернуться туда и обратно в историю браузера, так как это вызовет у меня запуск кода дважды: один раз, когда новое состояние изменилось, а другое, потому что $loationChangeStart уволен.

Я попытался использовать reloadOnSearch=false, но предотвратил изменения состояния, даже когда путь URL был изменен. Поэтому я, наконец, получил его для работы, выполнив следующие действия:

При изменении $location.search() для обновления параметров запроса используйте "hack" , чтобы временно отключить перезагрузку при поиске, задать параметры запроса, затем повторно включите перезагрузку.

$state.current.reloadOnSearch = false;

$location.search('query', [1,2]);

$timeout(function () {
  $state.current.reloadOnSearch = undefined;
});

Это гарантирует, что изменения параметров запроса не перезагружают состояние и что изменения пути URL будут перезагружать состояние должным образом.

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

$locationProvider.html5Mode(true);

$stateProvider
  .state('home', {
    url: '/?param1&param2&param3',
    templateUrl: 'home.html',
    controller: 'homeCtrl as home',
  });

Любые имена параметров на url являются необязательными при указании этого способа, но любые изменения этих имен параметров перезагружают состояние при нажатии кнопок назад и вперед в браузере.

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