Wyczyść historię i załaduj ponownie stronę podczas logowania / wylogowywania za pomocą Ionic Framework


80

Nie mam doświadczenia w tworzeniu aplikacji mobilnych z Ionic. Podczas logowania i wylogowywania muszę ponownie załadować stronę, aby odświeżyć dane, jednak $state.go('mainPage')przenosi użytkownika z powrotem do widoku bez przeładowywania - kontroler za nią nigdy nie jest wywoływany.

Czy istnieje sposób na wyczyszczenie historii i ponowne załadowanie stanu w Ionic?

Odpowiedzi:


124

Witamy w frameworku! W rzeczywistości routing w Ionic jest zasilany przez router ui . Prawdopodobnie powinieneś sprawdzić to poprzednie pytanie SO, aby znaleźć kilka różnych sposobów, aby to osiągnąć.

Jeśli chcesz tylko przeładować stan, możesz użyć:

$state.go($state.current, {}, {reload: true});

Jeśli faktycznie chcesz ponownie załadować stronę (tak jak w przypadku, chcesz ponownie załadować wszystko), możesz użyć:

$window.location.reload(true)

Powodzenia!


Chcę spakować wszystkie pliki css / js pobrane ze zdalnego serwera w index.html. Ale wolałbym je ponownie załadować tylko wtedy, gdy nastąpiła zmiana. Jak mam to zorganizować?
mylord

Nie jestem pewien, czy rozumiem Cię @mylord. Czy mówisz o przeładowaniu na żywo? Może interesuje Cię pamięć podręczna / manifest offline Html5, jak omówiono tutaj: tmkmobile.wordpress.com/2012/03/04/html5-offline-solution Myślę, że możesz próbować zrobić coś innego niż pierwotny cel pytania.
JimTheDev

13
$ state.go ($ state.current, {}, {reload: true}); to rozwiązanie u mnie nie działa.
IamStalker

@IamStalker Czy możesz podać jakieś dodatkowe informacje lub może przykładowo codepen / fiddle / plunk?
JimTheDev

9
$state.go($state.current, {}, {reload: true});nie działa, jeśli cache:true(co jest wartością domyślną, jeśli pominięto pamięć podręczną) w definicji stanu. Przetestowano w #ionic 1.0.0-RC2 i 1.0.0. Zobacz moją odpowiedź.
ABCD.ca

25

Okazało się, że odpowiedź JimTheDev działa tylko wtedy, gdy została cache:falseustawiona definicja stanu . Dzięki buforowaniu widoku możesz to zrobić, $ionicHistory.clearCache()a następnie, $state.go('app.fooDestinationView')jeśli nawigujesz z jednego stanu do tego, który jest buforowany, ale wymaga odświeżenia.

Zobacz moją odpowiedź tutaj, ponieważ wymaga prostej zmiany na Ionic i utworzyłem żądanie ściągnięcia: https://stackoverflow.com/a/30224972/756177


1
Dobry towar. W rzeczywistości nie używam tego w mojej aplikacji jonowej, więc doceniam kontynuację funkcji buforowania. Wygląda na to, że Twój PR przejdzie do wersji 1.0.1. Kiedy to zostanie opublikowane, zapiszę w moim oryginalnym poście, w którym napisałem o tobie i zachęciłem ludzi do przyjrzenia się.
JimTheDev

18

Poprawna odpowiedź:

$window.location.reload(true);

1
Ta odpowiedź została oznaczona jako niska jakość. Czy mógłbyś spróbować wyjaśnić, dlaczego jest to poprawna odpowiedź?
Jorge Leitao,

1
Ponieważ używa $windowzamiastwindow
EpokK

Masz rację w tym, że jeśli korzystasz ze składni .location.reload, sensowne jest użycie $ window. Zmieniłem odpowiedź powyżej, aby zachować spójność dla przyszłych czytelników. W niektórych przypadkach przydatna może być również składnia $ state.go.
JimTheDev,

Pomogła mi tylko ta odpowiedź, a nie zaznaczona
Michał

Kiedyś podobało mi się to podejście, ale niektórzy zgłaszali, że powoduje ono nieskończoną pętlę przeładowań na niektórych urządzeniach (Android 4.4, Chrome).
Oleg Cheremisin

18

Znalazłem rozwiązanie, które pomogło mi to zrobić. Ustawienie cache-view="false"na ion-viewtagu rozwiązało mój problem.

<ion-view cache-view="false" view-title="My Title!">
  ....
</ion-view>

wyłączenie widoku pamięci podręcznej powoduje znaczną utratę wydajności, należy unikać tej opcji. zamiast tego możesz obsługiwać zdarzenia ionicView. zobacz: stackoverflow.com/questions/25192172/ ...
ezain

@ezain, czy mógłbyś dać mi znać, w jaki sposób wpływa to na wydajność?
Rajeshwar

@Rajeshwar, gdy system pamięci podręcznej jest włączony, Ionic utrzymuje cały DOM wygenerowany przez widok w ukryciu, a gdy następuje zmiana widoku, nie trzeba ponownie obliczać DOM. Jeśli masz ciężki DOM i musisz go generować we wszystkich zmianach przejścia, możesz docenić opóźnienia w animacjach przejścia. Jeśli jedynym powodem wyłączenia pamięci podręcznej jest ponowne załadowanie kontrolera, użyj zdarzeń ionicView.
ezain

@ezain, Jest wiele sposobów zaimplementowania tej funkcji wyłączania pamięci podręcznej. Wypróbowałem prawie wszystkie, nic mi nie pomogło. A ten dał mi to, czego potrzebuję. I nie widzę żadnych opóźnień podczas ładowania tej strony, mimo że jest ona niewielka. Więc wolałem ten sposób niż inne sposoby.
Rajeshwar

11

Ponowne załadowanie strony nie jest najlepszym podejściem.

możesz obsłużyć zdarzenia zmiany stanu w celu ponownego załadowania danych bez ponownego ładowania samego widoku.

Przeczytaj o cyklu życia ionicView tutaj:

http://blog.ionic.io/navigating-the-changes/

i obsłuż zdarzenie beforeEnter w celu ponownego załadowania danych.

$scope.$on('$ionicView.beforeEnter', function(){
  // Any thing you can think of
});

Wydaje się, że to najlepsze podejście.
markau

konkretnie można sprawdzić, czy państwo jest z pamięci podręcznej, a jeśli tak, zadzwoń niektóre API, aby ją odświeżyć:$scope.$on('$ionicView.beforeEnter', function(scopes, states) { if (states.fromCache) { ... } }
jakub.g

@ jakub.g jeśli nie chcesz buforować widoku, możesz wyłączyć pamięć podręczną dla tego konkretnego widoku, jest prostsze.
ezain

6

W moim przypadku muszę wyczyścić tylko widok i ponownie uruchomić kontroler. Mogę zrozumieć mój zamiar za pomocą tego fragmentu:

$ionicHistory.clearCache([$state.current.name]).then(function() {
  $state.reload();
}

Pamięć podręczna nadal działa i wygląda na to, że wyczyszczono tylko widok.

ionic --version mówi 1.7.5.


Dodatek: Gdy stan ma parametry, należy je zdefiniować w widoku / identyfikacji stanu. Sprawdź ten
plik wklejany

Błędy w kodzie Poprawna wersja $ ionicHistory.clearCache ([$ state.current.name]). Then (function () {$ state.reload ();});
Kirill A

Brakuje tylko nawiasu
użytkownik623396

1

Żadne z wyżej wymienionych rozwiązań nie działało w przypadku nazwy hosta innej niż localhost!

Musiałem dodać notify: false do listy opcji, do których przechodzę $state.go, aby uniknąć wywoływania słuchaczy zmian Angular, zanim $window.location.reloadpołączenie zostanie wywołane. Ostateczny kod wygląda następująco:

$state.go('home', {}, {reload: true, notify: false});

>>> EDYCJA - w zależności od przeglądarki konieczne może być podanie $ timeout >>>

$timeout(function () { $window.location.reload(true); }, 100);

<<< KONIEC EDYCJI <<<

Więcej informacji na ten temat znajdziesz w dokumentacji ui-routera .


0

Próbowałem odświeżyć stronę za pomocą angularjs, kiedy zobaczyłem strony internetowe, pomyliłem się, ale żaden kod nie działał dla kodu, a następnie otrzymałem rozwiązanie do ponownego załadowania strony za pomocą

$state.go('path',null,{reload:true});

użyj tego w funkcji, która będzie działać.


0

Musiałem przeładować stan, aby paski przewijania działały. Nie działały, gdy przekraczały inny stan - „rejestracja”. Jeśli aplikacja została wymuszona po rejestracji i ponownie otwarta, tj. Przeszła bezpośrednio do stanu „początkowego”, paski przewijania działały. Żadne z powyższych rozwiązań nie zadziałało.

Gdy po rejestracji wymieniłem:

$state.go("home");

z

window.location = "index.html"; 

Aplikacja została ponownie załadowana, a paski przewijania działały.


0

Kontroler jest wywoływany tylko raz i POWINIENEŚ zachować ten model logiczny, co zwykle robię to:

Tworzę metodę $scope.reload(params)

Na początku tej metody dzwonię $ionicLoading.show({template:..}) aby pokazać mój niestandardowy spinner

Po zakończeniu procesu ponownego ładowania mogę zadzwonić $ionicLoading.hide() jako oddzwonienie

Na koniec dodaję wewnątrz przycisku ODŚWIEŻ ng-click = "reload(params)"

Jedynym minusem tego rozwiązania jest utrata systemu historii nawigacji jonowej

Mam nadzieję że to pomoże!


0

Jeśli chcesz ponownie załadować po zmianie widoku, musisz

$state.reload('state',{reload:true});

Jeśli chcesz, aby ten widok był nowym „korzeniem”, możesz powiedzieć ionic, że następnym widokiem będzie korzeń

 $ionicHistory.nextViewOptions({ historyRoot: true });
 $state.go('app.xxx');
 return;

Jeśli chcesz, aby kontrolery ładowały się ponownie po każdej zmianie widoku

app.config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider) {

$ionicConfigProvider.views.maxCache(0);


0

Jak wskazały kontrolery @ezain przeładowujące tylko wtedy, gdy jest to konieczne. Innym czystszym sposobem aktualizowania danych podczas zmiany stanów, zamiast ponownego ładowania kontrolera, jest wykorzystanie zdarzeń transmisji i nasłuchiwanie takich zdarzeń w kontrolerach, które muszą aktualizować dane w widokach.

Przykład: w funkcjach logowania / wylogowania możesz zrobić coś takiego:

$scope.login = function(){
    //After login logic then send a broadcast
    $rootScope.$broadcast("user-logged-in");
    $state.go("mainPage");
};
$scope.logout = function(){
   //After logout logic then send a broadcast
   $rootScope.$broadcast("user-logged-out");
   $state.go("mainPage");
};

Teraz w kontrolerze mainPage wyzwalaj zmiany w widoku, używając funkcji $ on, aby słuchać transmisji w kontrolerze mainPage w następujący sposób:

$scope.$on("user-logged-in", function(){
     //update mainPage view data here eg. $scope.username = 'John';
});

$scope.$on("user-logged-out", function(){
    //update mainPage view data here eg. $scope.username = '';
});

-1

Próbowałem wielu metod, ale stwierdziłem, że ta metoda jest absolutnie poprawna:

$window.location.reload();

Mam nadzieję, że pomoże to innym utknąć na wiele dni, takich jak ja z wersją: kątowa 1.5.5, jonowa 1.2.4, kątowa-ui-router 1.0.0

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.