Verwenden Sie dies innerhalb eines Versprechens in AngularJS

8

Gibt es eine Best-Practice-Lösung, um dies zu nutzen? In jQuery kann ich mein Objekt binden, um es in meinem Versprechen / Callback zu verwenden - aber in angularJS? Gibt es Best-Practice-Lösungen? Der Weg "var service = this;" Ich bevorzuge nicht ...

%Vor%

Gibt es Lösungen für dieses Problem? Wie kann ich im Rahmen des Versprechens Zugang zu Mitgliedern oder Methoden von meinem Dienst erhalten?

Vielen Dank im Voraus.

    
xyNNN 13.11.2014, 07:24
quelle

1 Antwort

18

Das generische Problem von dynamic this in einem Callback wird erklärt in dieser Antwort was sehr gut ist - ich werde nicht wiederholen, was Felix gesagt hat. Ich werde stattdessen vielversprechende Lösungen besprechen:

Versprechen werden unter der Promises / A + -Spezifikation angegeben, die es Versprechensbibliotheken ermöglicht, die gegenseitigen Versprechen nahtlos zu nutzen. Angular $ q verspricht Ehre, dass Spezifikation und dafür und Winkel Versprechen muss per Definition führen Sie die .then Callbacks als Funktionen - das heißt, ohne this . Im strikten Modus wird promise.then(fn) immer immer this zu undefined innerhalb fn (und window im nicht-strikten Modus) ausgewertet.

Die Begründung ist, dass ES6 um die Ecke ist und diese Probleme eleganter löst.

Also, was sind Ihre Möglichkeiten?

  • Einige Versprechen Bibliotheken bieten eine .bind Methode (Bluebird zum Beispiel), können Sie Verwenden Sie diese Versprechen in Angular und tauschen Sie $ q aus.
  • ES6, CoffeeScript, TypeScript und AtScript enthalten alle einen => Operator, der this bindet.
  • Sie können die ES5-Lösung mit .bind verwenden.
  • Sie können einen der Hacks in der oben erwähnten Antwort von Felix verwenden.

Hier sind diese Beispiele:

Binde hinzufügen - aka Promise#bind

Angenommen, Sie haben die obige Frage befolgt und beantwortet sollte tun können:

%Vor%

Verwenden einer Pfeilfunktion

%Vor%

Verwendung von .bind

%Vor%

Verwendung eines pre ES5 'hack'

%Vor%

Natürlich gibt es ein größeres Problem

Ihr aktuelles Design enthält keine Möglichkeit zu _know, wenn _myVariable verfügbar ist. Sie müssten es abfragen oder sich auf die interne Reihenfolge verlassen. Ich glaube, Sie können es besser machen und haben ein Design, bei dem Sie immer Code ausführen, wenn die Variable verfügbar ist:

%Vor%

Dann können Sie _myVariable via this._myVariable.then(function(value){ verwenden. Dies mag mühsam erscheinen, aber wenn Sie $q.all verwenden, können Sie dies leicht mit mehreren Werten tun, und dies ist absolut sicher hinsichtlich der Synchronisation des Zustands.

Wenn Sie es lazy laden wollen und es nicht das erste Mal aufrufen (das heißt, nur wenn myFunction aufgerufen wird) - ich verstehe das total. Sie können einen Getter verwenden und tun:

%Vor%

Nun wird es nur lazy geladen, wenn Sie es zum ersten Mal aufrufen.

    
Benjamin Gruenbaum 13.11.2014, 07:52
quelle

Tags und Links