Como recarregar o estado atual?


333

Estou usando o Angular UI Router e gostaria de recarregar o estado atual e atualizar todos os dados / executar novamente os controladores para o estado atual e seu pai.

Eu tenho 3 níveis de estado: directory.organisations.details

directory.organisations contém uma tabela com uma lista de organizações. Clicar em um item da tabela carrega directory.organisations.details com $ StateParams passando o ID do item. Portanto, no estado de detalhes, carrego os detalhes desse item, edito-os e salve os dados. Tudo bem até agora.

Agora preciso recarregar esse estado e atualizar todos os dados.

Eu tentei:

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

Que vai para o estado pai, mas não recarrega o controlador, acho que porque o caminho não mudou. Idealmente, eu só quero permanecer no estado directory.organisations.details e atualizar todos os dados no pai também.

Eu também tentei:

$state.reload()

Eu já vi isso na API WIKI por $ state.reload "(bug com os controladores sendo restabelecidos agora, corrigidos em breve)."

Qualquer ajuda seria apreciada?


7
Resolvi isso da seguinte maneira: $ state.transitionTo ($ state.current, $ stateParams, {reload: true, herdar: false, notificar: true});
Holland Risley 11/02

1
onde adicionar esse código?
precisa

Então o bug está corrigido agora? github.com/angular-ui/ui-router/wiki/…
jchnxu

Onde o código deve $state.transitionTo($state.current, $stateParams, {reload:true, inherit:false})ser adicionado? Ter esse mesmo problema com a atualização dos meus estados está perdendo todos os dados.
Evan Burbidge

Respostas:


565

Eu achei que essa era a maneira mais curta de atualizar o ui-router:

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

Atualização para versões mais recentes:

$state.reload();

Qual é um alias para:

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

Documentação: https://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state#methods_reload


21
Provavelmente vale a pena notar que nenhum deles também recarrega a página. Se você deseja recarregar o estado E a página, ui-routeracho que não há método para isso. Faça window.location.reload(true).
SimplGy

15
@SimpleAsCouldBe se você quisesse ser mais angular, poderia fazer $window.location.reload();. Embora isso pareça um pouco exagerado, poderia tornar os testes / zombarias / conhecer todas as dependências que um pedaço de código facilita um pouco as coisas.
Ededges

1
Apenas curioso, o que exatamente é "$ state.current" significa? Não consigo ver explicações claras sobre a API do ui-router, qualquer ajuda será apreciada, obrigado!
User2499325

3
@ user2499325: $ state.current retorna um objeto com todos os dados que você possui stateProvider: `` `{url:" / place /: placeId ", controller:" NewPlaceController ", controllerAs:" placeVM ", templateUrl:" places /new.place/new.place.details.html ", name:" index.places.placeDetails "}` ``
Xavier Haniquaut

1
Você pode substituir {} por $ stateParams se já tiver parâmetros carregados como tal: $ state.go ($ state.current, $ stateParams, {reload: true});
tsuz 29/01

154

Esta solução funciona no AngularJS V.1.2.2:

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

8
Onde você adicionaria isso para que não cause um loop infinito?
Pathsofdesign

5
Isso resolverá novamente os resolveitens do estado?
TheSharpieOne

7
Além disso, você não terá que injetar US $ stateParams se você mudar essa chamada para $ state.params
Jeff Ancel

4
Funciona muito melhor do que a resposta mais votada atual, na verdade recarrega a página. Se você tiver um problema de loop infinito, sua recarga provavelmente está no lugar errado. Estou apenas usando-o em um clique de botão
Dan

2
Um pouco atrasado para o @ManojG, mas você colocaria esse código em qualquer lugar que fosse necessário para recarregar - talvez em uma função de diretiva ng-click ou outro evento. Não deve ser feito em cada carregamento da página, por razões óbvias (loop infinito)
sricks

68

Essa seria a solução final. (inspirado na publicação de @ 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;
    });
});

Agora, sempre que precisar recarregar, basta ligar para:

$state.forceReload();

6
laço inifinito da morte
CS

6
Parece que você tem um interceptador em algum lugar que é acionado. Eu testei esta solução várias vezes e funciona bem.
MK

2
@MK Obrigado por essa nota. Ele me levou à solução do meu próprio problema diferente. Passei horas tentando descobrir por que meus pedidos estavam duplicando, depois triplicou etc. e tudo foi por causa de um interceptador ( github.com/witoldsz/angular-http-auth ).
Maciej Gurban

57

para estrutura iônica

$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


Funciona bem para mim, onde $state.gonão foi possível redirecionar para um novo estado. Obrigado @RouR. Salvou o meu dia.
Guillaume Wuip 6/08/2015

Acho que substitua $ state.go por $ state.transitionTo. Portanto, onde quer que você esteja chamando $ state.go, basta substituí-lo. Poderia ser algo como $ state.transitionTo ( 'tab-name', {chave: valor}, {recarga: true, herdar: true, notificadas: true}
Bill Pope

2
cache: false faz o truque .. mas quanto isso afeta o desempenho?
FrEaKmAn

alterar $ state.go com $ state.transitionTo para alterar o estado e recarregar @ManojG
Gery

Preciso incluir uma nova biblioteca para usar $state? Estou executando o iônico 1.4.0, angular 1.5.3
josinalvo

45

Provavelmente, a abordagem mais limpa seria a seguinte:

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

Podemos recarregar o estado apenas do HTML.


7
Você também pode usar ui-sref-opts = "{reload: 'child.state'}" para evitar recarregar a página inteira, onde 'child.state' é uma string que representa seu estado real.
Michael Fulton


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

13
$scope.reloadstat = function () { $state.go($state.current, {}, {reload: true}); };

7

se você quiser recarregar sua página inteira, como parece, basta injetar $ window no seu controller e então chamar

$window.location.href = '/';

mas se você quiser apenas recarregar sua visualização atual, injete $ scope, $ state e $ stateParams (este último, caso você precise alterar alguns parâmetros nesta próxima recarga, algo como o número da sua página) e chame-o em qualquer método do controlador:

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

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


6

Solução boba que sempre funciona.

$state.go("otherState").then(function(){
     $state.go("wantedState")
});

3

Para a v1.2.26 angular, nenhuma das opções acima funciona. Um ng-clique que chama os métodos acima terá que ser clicado duas vezes para fazer o estado recarregar.

Acabei emulando dois cliques usando $ 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 () exigiu dois cliques com o Angular 1.3.0-rc0, mas o transiçãoTo () funcionou bem. Talvez tente a atualização se você tem esse problema
sricks


3

Não sei por que nada disso parecia funcionar para mim; o que finalmente fez foi:

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

Isso foi com o Angular 1.4.0


2

Eu tinha várias visualizações aninhadas e o objetivo era recarregar apenas uma com conteúdo. Tentei abordagens diferentes, mas a única coisa que funcionou para mim é:

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

Nesse caso, apenas a visualização necessária seria recarregada e o cache ainda funcionaria.


recarregar verdadeiro ou falso, você mencionado como falso. false recarregará o conteúdo com as alterações mais recentes?
deadend 25/03

2

Sei que há várias respostas, mas a melhor maneira de fazer isso sem causar uma atualização completa da página é criar um parâmetro fictício na rota que desejo atualizar e, quando chamo a rota, passo uma número aleatório para o parâmetro fictício.

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

e então a chamada para essa rota

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

Funciona como um encanto e lida com as resoluções.


2

Você pode usar a resposta de @Rohan https://stackoverflow.com/a/23609343/3297761

Mas se você quiser fazer com que cada controlador seja carregado após uma alteração de exibição, você pode usar

myApp.config(function($ionicConfigProvider) { $ionicConfigProvider.views.maxCache(0); ... }

2

Se você estiver usando o ionic v1, a solução acima não funcionará, pois o ionic ativou o cache de modelos como parte do $ ionicConfigProvider.

A solução para isso é um pouco hacky - você deve definir o cache como 0 no arquivo ionic.angular.js:

$ionicConfigProvider.views.maxCache(0);

1

Eu tive esse problema que estava destruindo minha cabeça, meu roteamento é lido a partir de um arquivo JSON e, em seguida, alimentado em uma diretiva. Eu poderia clicar em um estado da interface do usuário, mas não consegui recarregar a página. Então, um colega meu me mostrou um pequeno truque para isso.

  1. Obtenha seus dados
  2. Na configuração de seus aplicativos, crie um estado de carregamento
  3. Salve o estado que você deseja ir no rootcope.
  4. Defina sua localização como "/ loading" no seu app.run
  5. No controlador de carregamento, resolva a promessa de roteamento e defina o local para o destino pretendido.

Isso funcionou para mim.

Espero que ajude

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.