2016-06-10 5 views
1

Wie kann ich eine Funktion starten, nachdem die Ansicht gerendert wurde? Ich muss zum Beispiel gemessene Breite einer Komponente erhalten, aber alles ist 0 oder NaN zumindest wenn auf die Ereignisse navigatedTo und loaded zugegriffen wird.Ereignis, wenn die Ansicht auf NativeScript gerendert wird

+0

proiva tatsächlichen Code von dem, was Sie versuchen zu erreichen –

+0

Sie könnten einen Timer mit einem setTimeout von 1 Millisekunde verwenden. Dieser Code wird ausgeführt, nachdem der gesamte Code ausgeführt wurde. –

+0

Ich versuche, Dimensionen zu sehen, nicht viel Code dort noch. Ich werde versuchen, diese Zeitverzögerung Idee auszuprobieren. – Terhoraj

Antwort

0

Sind Sie sicher, dass Sie "onNavigatedTo", nicht "onNavigatingTo" verwenden?

Dies sind alle page events.

+1

Überprüft und ja ich benutze das. – Terhoraj

2

Tun Sie zu dem Zeitpunkt, wenn Dinge gebaut und gezeichnet werden; die einzige Methode, die ich zuverlässig gefunden habe, zu arbeiten ist eigentlich so etwas wie:

exports.onNavigatingTo = function() { 
    setTimeout(codeAfterRender, 1); 
} 

function codeAfterRender() { 
/* do something cool */ 
} 

Der Grund, warum denn gerade wie eine normale Anwendung ist die UI ist immer noch nur ein einzelner Thread; also während JS läuft; Die Benutzeroberfläche kann nicht wirklich aktualisiert werden.

Der Trick besteht also darin, den Code so lange auszugeben, bis die JS-Engine wieder in den systemeigenen Code zurückkehrt. Der native Code rendert den Bildschirm und gibt die JS-Engine erneut ein.

Die einfachste Methode, Ihren Code zu verzögern, ist die Verwendung von setTimeout, da setTimeout in systemeigenem Code geplant ist. (Dies ist sehr ähnlich wie process.nextTick in Knoten verwenden.)

Ereignisschleife:

  • JavaScript-Code
  • JavaScript-Code -> Sie Schedule Timeout (die eigentlich in der india geplant ist)
  • JavaScript-Code Beendet die Ausführung
  • JavaScript-Laufzeit kehrt zurück zum systemeigenen Code
  • Nativer Code Rendert und verarbeitet alle verbleibenden Nachrichten.
  • systemeigenen Code Timer Feuer beginnt JS Motor Ihre SetTimeout Funktion
  • JavaScript-Code vorbei startet Ihre SetTimeout Routine
  • JavaScript-Code abgeschlossen ist, zu Nativeindia
  • -Code tritt zurück macht und verarbeitet alle Nachrichten
  • Rest Der systemeigene Code wird inaktiv.

Nur für etwas zusätzliche Klarheit; wie die Ereignisschleife funktioniert, ein echtes Beispiel; Eine Hilfsroutine, die ich für eine meiner Apps geschrieben habe, ist wie folgt:

Also würde ich diese Art von Code tun.

UpdateProgress("Processing 1/3") 
.then(function() { 
/* do some work, work freezes UI, so break it up */ 
    return UpdateProgress("Processing 2/3"); 
}) 
.then(function() { 
    /* do some more work, again work freezes UI */ 
    return UpdateProgress("Processing 3/3"); 
}) 
.then(function() { 
    /* do some more work, again work freezes UI */ 
    return ... 
}); 

Der Grund dafür ist, weil während NativeScript noch im JavaScript-Teil der Ereignisschleife die Anzeige nicht aktualisiert wird; Wenn Sie also viel zu tun haben und die Anzeige immer noch reaktionsschnell sein soll, müssen Sie den JavaScript-Teil der Ereignisschleife verlassen. Lassen Sie den nativen Teil alle ausstehenden Nachrichten behandeln, und fahren Sie dann im JS-Teil für den nächsten Teil der Verarbeitung fort. (Dies beseitigt auch ANRs auf Android) - Der Trick ist also, dass der Resolve Aufruf über ein setTimeout abgewickelt wird.

Ich habe auch einige Leute gesehen, die die On-Idle-Benachrichtigung verwenden; Es ist jedoch etwas komplizierter, die Ereignisse auf beiden Plattformen einzurichten. mit setTimeout ist einfacher und funktioniert genauso gut.

+0

Vielen Dank für die ausführliche Antwort! Bedeutet dies, dass 'setTimeout (codeAfterRender, 0);' genauso effektiv wäre? –

+1

Ja, 0 funktioniert auch. Es wird keinen Unterschied geben, 0 oder 1 Millisekunde sind identisch, wenn Sie die Arbeit abwerfen; zu dem Zeitpunkt, zu dem die JS-Engine beendet wird und zu nativ wechselt; Du hast mindestens 1 ms benutzt. ;-) Der einzige Grund, warum ich 1 über 0 bevorzuge, ist nur für den Fall, dass jemand einen Falsy-Test in einem setTimeout-Monkey oder in den Laufzeiten verwendet; Mein Code wird weiterhin ausgeführt. Wahrscheinlich eine sehr sehr sehr entfernte Möglichkeit; aber ich hedge immer meine Wetten ... ;-) – Nathanael

+0

Ich denke persönlich werde ich 'setTimeout (codeAfterRender, 0);' bevorzugen, damit die Absicht des Codes dem Leser klarer wird - dass dies nicht benutzt wird eine absichtliche Verzögerung einführen. Vielen Dank für Ihre tolle Antwort! –

Verwandte Themen