Как перезагрузить текущее состояние?

333

Я использую Angular UI Router и хотел бы перезагрузить текущее состояние и обновить все данные / перезапустить контроллеры для текущего состояния и его родителя.

У меня есть 3 уровня государства: directory.organisations.details

directory.organisations содержит таблицу со списком организаций. Нажатие на элемент в таблице загружает directory.organisations.details с $ StateParams, передающим идентификатор элемента. Поэтому в состоянии детали я загружаю детали для этого элемента, редактирую их и затем сохраняю данные. Пока все хорошо.

Теперь мне нужно перезагрузить это состояние и обновить все данные.

Я пытался:

 $state.transitionTo('directory.organisations');

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

Я также попробовал:

$state.reload()

Я видел это в API WIKI для $ state.reload "(ошибка с переустановкой контроллеров прямо сейчас, исправление в ближайшее время)".

Любая помощь будет оценена?

Голландия Рисли
источник
7
Я решил это следующим образом: $ state.transitionTo ($ state.current, $ stateParams, {reload: true, наследовать: false, notify: true});
Голландия Рисли
1
куда добавить этот код?
Manoj G
Значит ошибка исправлена ​​прямо сейчас? github.com/angular-ui/ui-router/wiki/…
jchnxu
Куда должен $state.transitionTo($state.current, $stateParams, {reload:true, inherit:false})быть добавлен код ? При такой же проблеме с перезагрузкой моих состояний теряются все данные.
Эван Бербидж

Ответы:

565

Я обнаружил, что это самый короткий рабочий способ обновления с помощью ui-router:

$state.go($state.current, {}, {reload: true}); //second parameter is for $stateParams

Обновление для более новых версий:

$state.reload();

Какой псевдоним для:

$state.transitionTo($state.current, $stateParams, { 
  reload: true, inherit: false, notify: true
});

Документация: https://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state#methods_reload

Рохан
источник
21
Вероятно, стоит отметить, что ни один из них на самом деле не перезагружает страницу. Если вы хотите перезагрузить состояние И страницу, ui-routerя думаю , что нет никакого способа для этого. Есть window.location.reload(true).
SimplGy
15
@SimpleAsCouldBe, если вы хотите быть более откровенным об этом, вы можете сделать $window.location.reload();. Хотя это кажется немного излишним, это может сделать тестирование / моделирование / знание всех зависимостей частью кода более простым делом.
хеджирует
1
Просто любопытно, что именно означает «$ state.current»? Я не вижу четких объяснений по API ui-router, любая помощь будет оценена, спасибо!
user2499325
3
@ user2499325: $ state.current возвращает объект со всеми данными, которые у вас есть. StateProvider: `` `{url:" / place /: placeId ", controller:" NewPlaceController ", controllerAs:" placeVM ", templateUrl:" place /new.place/new.place.details.html ", name:" index.places.placeDetails "}` ``
Ксавье Ханикво
1
Вы можете заменить {} на $ stateParams, если у вас уже есть параметры, загруженные как таковые: $ state.go ($ state.current, $ stateParams, {reload: true});
Цуз
154

Это решение работает в AngularJS V.1.2.2:

$state.transitionTo($state.current, $stateParams, {
    reload: true,
    inherit: false,
    notify: true
});
Голландия Рисли
источник
8
Куда бы вы добавили это, чтобы оно не вызывало бесконечный цикл?
Pathsofdesign
5
Это перерешит resolveпункты государства?
TheSharpieOne
7
Кроме того, вам не придется вводить $ stateParams, если вы измените этот вызов на $ state.params
Джефф Ансель
4
Работает намного лучше, чем текущий ответ с наибольшим количеством голосов, фактически перезагружает страницу. Если у вас есть проблема с бесконечным циклом, ваша перезагрузка, вероятно, не в том месте. Я использую его только по нажатию кнопки
Dan
2
Немного запоздало для @ManojG, но вы бы поместили этот код в любое место, где вам нужно выполнить принудительную перезагрузку - возможно, в функции директивы ng-click или в другом событии. Это не должно быть сделано при каждой загрузке страницы по очевидным причинам (бесконечный цикл)
sricks
68

Это было бы окончательное решение. (вдохновленный постом @ Hollan_Risley)

'use strict';

angular.module('app')

.config(function($provide) {
    $provide.decorator('$state', function($delegate, $stateParams) {
        $delegate.forceReload = function() {
            return $delegate.go($delegate.current, $stateParams, {
                reload: true,
                inherit: false,
                notify: true
            });
        };
        return $delegate;
    });
});

Теперь, когда вам нужно перезагрузить, просто позвоните:

$state.forceReload();
MK
источник
6
inifinit петля смерти
CS
6
Похоже, у вас где-то есть перехватчик, который срабатывает. Я протестировал это решение несколько раз, и оно отлично работает.
MK
2
@ МК Спасибо за эту записку. Это подтолкнуло меня к решению моей собственной, другой проблемы. Я часами пытался выяснить, почему мои запросы удваивались, затем утраивались и т. Д., И все это из-за перехватчика ( github.com/witoldsz/angular-http-auth ).
Мацей Гурбан
57

для ионного каркаса

$state.transitionTo($state.current, $state.$current.params, { reload: true, inherit: true, notify: true });//reload

$stateProvider.
  state('home', {
    url: '/',
    cache: false, //required

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

RouR
источник
Работает нормально для меня, где $state.goне удалось перенаправить на новое состояние. Спасибо @RouR. Спас мой день.
Гийом Вуйп
Я думаю заменить $ state.go на $ state.transitionTo. Поэтому, где бы вы ни называли $ state.go, просто замените это. Это может выглядеть примерно так: $ state.transitionTo ('tab-name', {key: value}, {reload: true, наследовать: true, notify: true}
Билл Папа
2
cache: false делает трюк .. но насколько это влияет на производительность?
FrEaKmAn
измените $ state.go с помощью $ state.transitionTo, чтобы изменить состояние и перезагрузить @ManojG
Gery
Нужно ли включать новую библиотеку для использования $state? Я бегу ионный 1.4.0, угловой 1.5.3
josinalvo
45

Вероятно, более чистый подход будет следующим:

<a data-ui-sref="directory.organisations.details" data-ui-sref-opts="{reload: true}">Details State</a>

Мы можем перезагрузить состояние только из HTML.

Вайбхав Пачаури
источник
7
Вы также можете использовать ui-sref-opts = "{reload: 'child.state'}", чтобы избежать перезагрузки всей страницы, где child.state - строка, представляющая ваше фактическое состояние.
Майкл Фултон
21

Ответ @Holland Risley теперь доступен в виде API в последнем UI-роутере.

$state.reload();

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

http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state

Muthukannan Kanniappan
источник
16
$state.go($state.current, $stateParams, {reload: true, inherit: false});
Уэстон Гангер
источник
13
$scope.reloadstat = function () { $state.go($state.current, {}, {reload: true}); };
user7961355
источник
7

если вы хотите перезагрузить всю страницу, как кажется, просто введите $ window в ваш контроллер и затем вызовите

$window.location.href = '/';

но если вы хотите только перезагрузить текущее представление, введите $ scope, $ state и $ stateParams (последнее на тот случай, если вам нужно изменить некоторые параметры в предстоящей перезагрузке, например, номер вашей страницы), тогда вызовите это в любом метод контроллера:

$stateParams.page = 1;
$state.reload();

AngularJS v1.3.15 angular-ui-router v0.2.15

MarcoSantana
источник
6

Глупый обходной путь, который всегда работает.

$state.go("otherState").then(function(){
     $state.go("wantedState")
});
Fanchi
источник
3

Для угловых v1.2.26, ни один из вышеперечисленных не работает. Щелчок ng, который вызывает вышеупомянутые методы, должен будет щелкнуть дважды , чтобы перезагрузить состояние.

Так что я в итоге эмулировал 2 клика, используя $ timeout.

$provide.decorator('$state',
        ["$delegate", "$stateParams", '$timeout', function ($delegate, $stateParams, $timeout) {
            $delegate.forceReload = function () {
                var reload = function () {
                    $delegate.transitionTo($delegate.current, angular.copy($stateParams), {
                        reload: true,
                        inherit: true,
                        notify: true
                    })
                };
                reload();
                $timeout(reload, 100);
            };
            return $delegate;
        }]);
танос панус
источник
Navigation.reload () требовал двух щелчков с Angular 1.3.0-rc0, но transitionTo () работал нормально. Может быть, попробуйте обновить, если у вас есть эта проблема
sricks
3

Все не удалось для меня. Единственное, что сработало ... это добавление cache-view = "false" в представление, которое я хочу перезагрузить при переходе к нему.

из этого выпуска https://github.com/angular-ui/ui-router/issues/582

Hans
источник
3
Вы должны добавить, что это для ионных
Ladmerc
3

Не уверен, почему ни один из них, казалось, не работал для меня; тот, который наконец сделал это, был:

$state.reload($state.current.name);

Это было с Angular 1.4.0

BarrySW19
источник
2

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

//to reload
$stateParams.reload = !$stateParams.reload; //flip value of reload param
$state.go($state.current, $stateParams);

//state config
$stateProvider
  .state('app.dashboard', {
    url: '/',
    templateUrl: 'app/components/dashboard/dashboard.tmpl.html',
    controller: 'DashboardController',
    controllerAs: 'vm',
    params: {reload: false} //add reload param to a view you want to reload
  });

В этом случае только необходимое представление будет перезагружено, и кэширование все еще будет работать.

Дмитрий Невзоров
источник
перезагрузите истину или ложь, вы упомянули как ложь. false перезагрузит контент с последними изменениями?
Тупик
2

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

            .state("coverage.check.response", {
                params: { coverageResponse: null, coverageResponseId: 0, updater: 1 },
                views: {
                    "coverageResponse": {
                        templateUrl: "/Scripts/app/coverage/templates/coverageResponse.html",
                        controller: "coverageResponseController",
                        controllerAs: "vm"
                    }
                }
            })

а затем звонок на этот маршрут

$state.go("coverage.check.response", { coverageResponse: coverage, updater: Math.floor(Math.random() * 100000) + 1 });

Работает как шарм и обрабатывает решает.

ewahner
источник
2

Вы можете использовать ответ @Rohan https://stackoverflow.com/a/23609343/3297761

Но если вы хотите настроить каждый контроллер после изменения представления, вы можете использовать

myApp.config(function($ionicConfigProvider) { $ionicConfigProvider.views.maxCache(0); ... }
EduLopez
источник
2

Если вы используете ionic v1, вышеуказанное решение не будет работать, так как ionic включил кэширование шаблонов как часть $ ionicConfigProvider.

Обойти это немного нелепо - вы должны установить кэш на 0 в файле ionic.angular.js:

$ionicConfigProvider.views.maxCache(0);
Maksood
источник
1

У меня была эта проблема, это разрушало мою голову, моя маршрутизация читалась из файла JSON и затем передавалась в директиву. Я мог бы щелкнуть на пользовательском интерфейсе, но не смог перезагрузить страницу. Так что мой коллега показал мне хороший трюк для этого.

  1. Получите ваши данные
  2. В конфиге ваших приложений создайте состояние загрузки
  3. Сохраните состояние, в котором вы хотите перейти в корневой области.
  4. Установите ваше местоположение "/ loading" в вашем app.run
  5. В контроллере загрузки разрешите обещание маршрутизации, а затем установите местоположение в соответствии с предполагаемой целью.

Это сработало для меня.

Надеюсь, поможет

Эван Бербидж
источник