web-dev-qa-db-de.com

ionViewWillEnter vs ionViewDidEnter

Wenn wir eine Aufgabe, die bereits im Cache ist, nicht erneut initiieren möchten, besteht kein Zweifel, dass wir ionDidLoad verwenden werden.

Nehmen wir nun an, dass wir jedes Mal, wenn wir eine Ansicht betreten, eine Aufgabe ausführen müssen. Wie können wir zwischen ionViewWillEnter vs ionViewDidEnter wählen.

Ich habe dazu keine klare Richtlinie gefunden.

Zum Beispiel: 
1) NavParams abrufen 
2) Aufruf von REST api 
3) Variable deklarieren 
4) Initiieren Sie etwas, nachdem das DOM-Element vollständig geladen wurde (zB: google map init)

Zusätzliche Anmerkung:  
Ich suche nach einer Antwort, die eindeutig in der Ionendokumentation enthalten ist. Was ich vorhabe zu wissen, ist, was ist das Für und Wider, wenn in ionViewWillEnter vs ionViewDidEnter

beispiel: Das Einleiten in ionViewDidEnter führt zu einer Verzögerung (zum Beispiel bin ich mir nicht sicher) - sogar der unbedeutende

15
stackdisplay

sebaferreras Antwort ist toll, aber es fehlen einige Punkte.

Zunächst zu ionischer Lebenszyklus . Wenn Sie alle ionic Ereignisse aufschreiben und ein console.log in jedem sehen Sie das Szenario:

constructor --> ionViewDidLoad --> ionViewWillEnter --> ionViewDidEnter --> ionViewWillLeave --> ionViewDidLeave --> ionViewWillUnload.

constructor wird zuerst ausgeführt, wenn die Seite gestartet wird. Hier können Sie am besten Standardwerte für Ihre Variablen deklarieren.
ionViewDidLoad wird ausgelöst, wenn die Ansicht vollständig geladen ist. Dies bedeutet, dass Sie hier ein DOM-Element anhängen können.

ionViewWillEnter wird ausgeführt, wenn die Seite im Begriff ist, aufzurufen und die aktive Seite zu werden. ionViewDidEnter wird ausgeführt, wenn die Seite vollständig eingegeben wurde und jetzt die aktive Seite ist. ionViewDidEnter wird nach allen synchronen in ionViewWillEnter abgeschlossen. Um dies zu beweisen, fügen Sie einfach schweren Code in ionViewWillEnter ein:

ionViewWillEnter(){
    console.log("ionViewWillEnter")
    for(let i = 0; i < 100000; i++){
      console.log(i);
    }
}
ionViewDidEnter(){
    console.log("ionViewDidEnter")
}

Führen Sie Ihren Code aus und Sie werden feststellen, dass das Starten Ihrer Seite so lange dauert. Fügen Sie also niemals schweren synchronen Code in ionViewWillEnter ein. Verwenden Sie einfach asynchrones in ionViewWillEnter und verschieben Sie alle synchronen Code zu ionViewDidEnter. Weil dort Ihre Seite eingetragen ist und es eine bessere UX macht.

44
Duannx

Die Antwort ist ziemlich einfach und wie immer ist der beste Weg, um zu sehen, was hinter den Kulissen los ist, den Quellcode von Ionic zu überprüfen.

Um es kurz zu machen: der Lebenszyklus-Hook ionViewWillEnter wird ausgelöst, bevor der Seitenübergang beginnt, und ionViewDidEnter wird ausgelöst, nachdem der Übergang abgeschlossen ist. Bitte schauen Sie am Ende dieser Antwort nach, um die Referenz zum Quellcode zu sehen.

Wann sollten Sie jeden dieser Haken verwenden? Es muss mehrere mögliche Szenarien geben, daher sind dies nur einige Ideen, die auf einigen Anwendungen basieren, an denen ich gearbeitet habe.

  • Manchmal möchten Sie einige Informationen auf der Seite jedes Mal aktualisieren, wenn der Benutzer diese Seite öffnet. Dies erfordert möglicherweise eine HTTP-Anforderung an eine Remote-API, um Daten abzurufen. In diesem Fall könnte man sagen, dass die Verwendung von IonViewWillEnter die richtige Option ist, sodass Sie die Anfrage so schnell wie möglich stellen können und die Antwort schneller erhalten.

  • Dasselbe gilt, wenn Sie aus irgendeinem Grund mit dem DOM interagieren müssen, da das DOM beim Ausführen von IonViewWillEnter bereits geladen wurde. Dies könnte Ihnen helfen, die Seite so schnell wie möglich zu initialisieren und mit etwas Glück die Seite könnte dem Benutzer bereit zur Verwendung angezeigt werden.

  • Dasselbe gilt, wenn Sie die Ansicht mit einigen Parametern initialisieren müssen, die Sie aus der vorherigen Ansicht erhalten. In diesem Fall können Sie, da dies eine sehr einfache Operation ist, den Lebenszyklus-Hook ionViewWillEnter verwenden. Die Ansicht wird dem Benutzer bereits initialisiert angezeigt.

Wann sollten Sie dann ionViewDidEnter verwenden? 

  • Ich habe festgestellt, dass beim Ausführen der App auf sehr alten Android-Geräten (mit weniger als 512 MB - 1 GB RAM) die Animation etwas verzögert sein kann, wenn eine Anforderung an die API in ionViewWillEnter gestellt wird Eine gute Idee, diese Anforderungen an die API in ionViewDidEnter zu stellen, um sicherzustellen, dass die Animation abgeschlossen ist

  • In einigen Apps wurde ich gebeten, den Elementen der gepushten Seite ein paar ausgefallene Animationen hinzuzufügen, z. B. einen Teil des Inhalts von unten nach unten ziehen, einige andere Elemente nach einer Verzögerung ausblenden und so weiter. Sie können dazu kantige Animationen verwenden (um das Timing steuern zu können). Die beste Möglichkeit, Verzögerungen bei diesen Animationen zu vermeiden, ist der ionViewDidEnter-Hook. Auf diese Weise können Sie dem Benutzer das Gefühl geben, dass die Animationen der Elemente auf dieser Seite eine Fortsetzung des Übergangs der Seite selbst sind.


Sie können einen Blick auf den NavControllerBase-Code werfen:

1) IonViewWillEnter

// around line 666...
_transitionStart(...): Promise<NavResult> {

    // ...

    // around line 700...

    // create a callback that needs to run within zone
    // that will fire off the willEnter/Leave lifecycle events at the right time
    transition.beforeAddRead(this._viewsWillLifecycles.bind(this, enteringView, leavingView));

   // ...

}

Und...

  // around line 805...
  _viewsWillLifecycles(enteringView: ViewController, leavingView: ViewController) {
    if (enteringView || leavingView) {
      this._zone.run(() => {
        // Here, the order is important. WillLeave must be called before WillEnter.
        leavingView && this._willLeave(leavingView, !enteringView);
        enteringView && this._willEnter(enteringView);
      });
    }
  }

Wenn Sie die beforeAddRead-Methode von der animation.d.ts-Definition aus überprüfen, wird Folgendes angezeigt:

/**
* Add a function which contains DOM reads, which will run
* before the animation begins.
*/
beforeAddRead(domReadFn: Function): Animation;

So können wir jetzt sicher sein, dass der Lifecycle-Hook ionViewWillEnterausgeführt wird, bevor der Seitenübergang beginnt.

2) IonViewDidEnter

Dieser ist ein bisschen einfacher. Wieder in derselben NavControllerBase:

// around line 743...
  _transitionFinish(...): NavResult {

    // ...

    // around line 753...
    if (hasCompleted) {
      // transition has completed (went from 0 to 1)
      if (enteringView) {
        enteringName = enteringView.name;
        this._didEnter(enteringView);
      }

      // ..

    }

    // ...

  }

Und 

// around line 939...
  _didEnter(view: ViewController) {
    assert(this.isTransitioning(), 'nav controller should be transitioning');
    assert(NgZone.isInAngularZone(), 'callback should be zoned');

    try {
      view._didEnter();
      this.viewDidEnter.emit(view);
      this._app.viewDidEnter.emit(view);
    } catch (e) {
      this._errHandler && this._errHandler.handleError(e);
    }
  }

Aus diesem Grund können wir sagen, dass der _ionViewDidEnterLifecycle-Hook ausgelöst wird, nachdem der Übergang abgeschlossen ist.

8
sebaferreras

Wenn Sie die Aufgabe ausführen möchten, bevor die Ansicht angezeigt wird, verwenden Sie ionViewWillEnter . Wenn Sie die Aufgabe nach der Ansicht ausführen möchten, verwenden Sie ionViewDidEnter .

Das hängt ganz vom Szenario ab. Wenn Sie beispielsweise die Eigenschaften des ui-Elements ändern möchten, bevor die Ansicht angezeigt wird, verwenden Sie ionViewWillEnter. In den Beispielen Ihrer Frage: 4) Initiieren Sie etwas, nachdem das DOM-Element vollständig geladen wurde (zB: google map init.). In diesem Szenario können Sie also ionViewDidEnter verwenden 

0
H S Progr