Comment recharger l'état actuel?

333

J'utilise Angular UI Router et je voudrais recharger l'état actuel et actualiser toutes les données / réexécuter les contrôleurs pour l'état actuel et son parent.

J'ai 3 niveaux d'état: directory.organisations.details

directory.organisations contient un tableau avec une liste d'organisations. Cliquer sur un élément dans le tableau charge directory.organisations.details avec $ StateParams en passant l'ID de l'élément. Donc, dans l'état des détails, je charge les détails de cet élément, les modifie puis enregistre les données. Très bien jusqu'à présent.

Maintenant, je dois recharger cet état et actualiser toutes les données.

J'ai essayé:

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

Ce qui va à l'état parent mais ne recharge pas le contrôleur, je suppose que le chemin n'a pas changé. Idéalement, je veux simplement rester dans l' état directory.organisations.details et actualiser toutes les données dans le parent également.

J'ai aussi essayé:

$state.reload()

J'ai vu cela sur l'API WIKI pour $ state.reload "(bug avec les contrôleurs qui se réinstalle en ce moment, corrige bientôt)."

Toute aide serait appréciée?

Holland Risley
la source
7
J'ai résolu cela comme suit: $ state.transitionTo ($ state.current, $ stateParams, {reload: true, inherit: false, notify: true});
Holland Risley
1
où ajouter ce code?
Manoj G
Donc, le bug est corrigé en ce moment? github.com/angular-ui/ui-router/wiki/…
jchnxu
Où faut- $state.transitionTo($state.current, $stateParams, {reload:true, inherit:false})il ajouter le code ? Avoir ce même problème avec le rechargement de mes états, c'est perdre toutes les données.
Evan Burbidge,

Réponses:

565

J'ai trouvé que c'était le moyen de travail le plus court pour rafraîchir avec ui-router:

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

Mise à jour pour les versions plus récentes:

$state.reload();

Qui est un alias pour:

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

Documentation: https://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state#methods_reload

Rohan
la source
21
Il vaut probablement la peine de noter qu'aucun de ceux-ci ne recharge également la page. Si vous voulez recharger l'état ET la page, il n'y a pas de ui-routerméthode pour ça je pense. Faites window.location.reload(true).
SimplGy
15
@SimpleAsCouldBe si vous vouliez être plus anguleux à ce sujet, vous pourriez le faire $window.location.reload();. Bien que cela semble un peu exagéré, cela pourrait rendre les tests / moqueries / connaître toutes les dépendances un morceau de code a des choses un peu plus faciles.
edhedges
1
Juste curieux, que signifie exactement "$ state.current"? Je ne vois pas d'explications claires sur l'API de ui-router, toute aide sera appréciée, merci!
user2499325
3
@ user2499325: $ state.current renvoie un objet avec toutes les données que vous avez en vous stateProvider: `` `{url:" / place /: placeId ", controller:" NewPlaceController ", controllerAs:" placeVM ", templateUrl:" places /new.place/new.place.details.html ", nom:" index.places.placeDetails "}` ``
Xavier Haniquaut
1
Vous pouvez remplacer {} par $ stateParams si vous avez déjà des paramètres chargés comme tel: $ state.go ($ state.current, $ stateParams, {reload: true});
tsuz
154

Cette solution fonctionne dans AngularJS V.1.2.2:

$state.transitionTo($state.current, $stateParams, {
    reload: true,
    inherit: false,
    notify: true
});
Holland Risley
la source
8
Où ajouteriez-vous cela pour qu'il ne provoque pas de boucle infinie?
Pathsofdesign
5
Cela résoudra-t-il les resolvearticles de l'État?
TheSharpieOne
7
De plus, vous n'aurez pas à injecter $ stateParams si vous changez cet appel en $ state.params
Jeff Ancel
4
Fonctionne beaucoup mieux que la réponse actuellement la plus votée, recharge en fait la page. Si vous avez le problème de boucle infinie, votre rechargement est probablement au mauvais endroit. Je ne l'utilise que sur un clic de bouton
Dan
2
Un peu tard pour @ManojG mais vous mettriez ce code partout où vous aurez besoin de forcer un rechargement - peut-être dans une fonction directive ng-click ou un autre événement. Cela ne devrait pas être fait à chaque chargement de page pour des raisons évidentes (boucle infinie)
sricks
68

Ce serait la solution finale. (inspiré par le post 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;
    });
});

Maintenant, chaque fois que vous devez recharger, appelez simplement:

$state.forceReload();
MK
la source
6
boucle inifinit de la mort
CS
6
On dirait que vous avez un intercepteur quelque part qui se déclenche. J'ai testé cette solution plusieurs fois et cela fonctionne très bien.
MK
2
@MK Merci pour cette note. Cela m'a orienté vers la solution de mon propre problème différent. J'ai passé des heures à essayer de savoir pourquoi mes demandes étaient doublées, puis triplées, etc. et tout cela à cause d'un intercepteur ( github.com/witoldsz/angular-http-auth ).
Maciej Gurban
57

pour cadre ionique

$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
la source
Fonctionne bien pour moi où $state.gon'a pas réussi à rediriger vers un nouvel état. Merci @RouR. J'ai sauvé ma journée.
Guillaume Wuip
Je pense que remplacer $ state.go par $ state.transitionTo. Donc, partout où vous appelez $ state.go, remplacez-le. Cela pourrait ressembler à $ state.transitionTo ('tab-name', {key: value}, {reload: true, inherit: true, notify: true}
Bill Pope
2
cache: false fait l'affaire ... mais dans quelle mesure affecte-t-il les performances?
FrEaKmAn
change $ state.go avec $ state.transitionTo pour changer d'état et recharger @ManojG
Gery
Dois-je inclure une nouvelle bibliothèque à utiliser $state? Je cours ionique 1.4.0, angulaire 1.5.3
josinalvo
45

L'approche la plus propre serait probablement la suivante:

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

Nous pouvons recharger l'état à partir du HTML uniquement.

Vaibhav Pachauri
la source
7
Vous pouvez également utiliser ui-sref-opts = "{reload: 'child.state'}" pour éviter de recharger la page entière, où 'child.state' est une chaîne représentant votre état réel.
Michael Fulton
21

La réponse de @Holland Risley est maintenant disponible sous forme d'api dans le dernier ui-router.

$state.reload();

Une méthode qui force à recharger l'état actuel. Toutes les résolutions sont résolues à nouveau, les contrôleurs sont rétablis et les événements sont déclenchés à nouveau.

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

Muthukannan Kanniappan
la source
16
$state.go($state.current, $stateParams, {reload: true, inherit: false});
Weston Ganger
la source
13
$scope.reloadstat = function () { $state.go($state.current, {}, {reload: true}); };
user7961355
la source
7

si vous voulez recharger votre page entière, comme il semble, injectez simplement $ window dans votre contrôleur, puis appelez

$window.location.href = '/';

mais si vous souhaitez uniquement recharger votre vue actuelle, injectez $ scope, $ state et $ stateParams (ces derniers au cas où vous auriez besoin de modifier certains paramètres lors de ce rechargement à venir, quelque chose comme votre numéro de page), puis appelez-le dans n'importe quel méthode du contrôleur:

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

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

MarcoSantana
la source
6

Solution idiote qui fonctionne toujours.

$state.go("otherState").then(function(){
     $state.go("wantedState")
});
Fanchi
la source
3

Pour la version angulaire v1.2.26, aucun des éléments ci-dessus ne fonctionne. Un ng-click qui appelle les méthodes ci-dessus devra être cliqué deux fois pour que l'état se recharge.

J'ai donc fini par émuler 2 clics en utilisant $ 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;
        }]);
thanos panousis
la source
Navigation.reload () a nécessité deux clics avec Angular 1.3.0-rc0, mais la transitionTo () a bien fonctionné. Essayez peut-être de mettre à niveau si vous rencontrez ce problème
sricks
3

Tout a échoué pour moi. La seule chose qui a fonctionné ... est d'ajouter cache-view = "false" dans la vue que je veux recharger en y accédant.

de ce numéro https://github.com/angular-ui/ui-router/issues/582

Hans
la source
3
Vous devez ajouter que c'est pour ionique
Ladmerc
3

Je ne sais pas pourquoi aucun de ces éléments ne semblait fonctionner pour moi; celui qui l'a finalement fait était:

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

C'était avec Angular 1.4.0

BarrySW19
la source
2

J'avais plusieurs vues imbriquées et l'objectif était de recharger une seule avec du contenu. J'ai essayé différentes approches mais la seule chose qui a fonctionné pour moi est:

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

Dans ce cas, seule la vue nécessaire serait rechargée et la mise en cache fonctionnerait toujours.

Dmitriy Nevzorov
la source
recharger vrai ou faux, u mentionné comme faux. false rechargera le contenu avec les dernières modifications?
deadend
2

Je sais qu'il y a eu un tas de réponses, mais la meilleure façon que j'ai trouvée de le faire sans provoquer une actualisation de la page complète est de créer un paramètre factice sur la route que je veux actualiser, puis lorsque j'appelle la route, je passe dans un nombre aléatoire au paramètre fictif.

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

puis l'appel à cette route

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

Fonctionne comme un charme et gère les résolutions.

ewahner
la source
2

Vous pouvez utiliser @Rohan answer https://stackoverflow.com/a/23609343/3297761

Mais si vous voulez que chaque contrôleur soit rechargé après un changement de vue, vous pouvez utiliser

myApp.config(function($ionicConfigProvider) { $ionicConfigProvider.views.maxCache(0); ... }
EduLopez
la source
2

Si vous utilisez ionic v1, la solution ci-dessus ne fonctionnera pas car ionic a activé la mise en cache des modèles dans le cadre de $ ionicConfigProvider.

Contournement pour cela est un peu hacky - vous devez définir le cache à 0 dans le fichier ionic.angular.js:

$ionicConfigProvider.views.maxCache(0);
Maksood
la source
1

J'ai eu ce problème, ça me faisait mal à la tête, mon routage est lu à partir d'un fichier JSON puis alimenté dans une directive. Je pouvais cliquer sur un état d'interface utilisateur mais je n'ai pas pu recharger la page. Un de mes collègues m'a donc montré un bon petit truc pour ça.

  1. Obtenez vos données
  2. Dans la configuration de vos applications, créez un état de chargement
  3. Enregistrez l'état dans lequel vous voulez aller dans le rootscope.
  4. Définissez votre emplacement sur "/ loading" dans votre app.run
  5. Dans le contrôleur de chargement, résolvez la promesse de routage, puis définissez l'emplacement sur la cible souhaitée.

Cela a fonctionné pour moi.

J'espère que ça aide

Evan Burbidge
la source