2015-05-14 14 views
7

Ich bin ziemlich neu in der ganzen AngularJS-Welt und wie es funktioniert, aber ich kämpfe darum, dass es funktioniert wie erwartet. Ich weiß, dass es etwas damit zu tun hat, wie ich $http.get() benutze und versuche, die Variablen meinem Controller zuzuordnen, aber ich kann es einfach nicht herausfinden.

Mit $scope statt this ich es bekommen kann arbeiten, aber wenn möglich, ich würde es vorziehen, zu verwenden this so kann ich "Controller als"

-Code verwenden:

app.controller('ctrlSuppliers', function($http){ 

    this.supplierList = {}; 

    $http.get("http://some_url_here") 
      .success(function(response) { this.supplierList = response.records;}) 
      .error(function() { this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting Details'}];}); 
}); 

Aus diesem Beispiel, ich kann dann nicht auf Ergebnisse von der $http.get Anfrage innerhalb der supplierList innerhalb der HTML-Seite zugreifen (dh zeigt keine Ergebnisse)

Ich weiß, wenn ich den Controller zu $scope ändere, kann ich auf diese Daten zugreifen (obwohl nicht das gleiche Format wie oben verwendet), und ich weiß auch, dass die Daten mit console.log(this.supplierList) innerhalb der .success Aufruf aufgefüllt werden.

Ich weiß auch, dass der Grund, warum es nicht funktioniert, weil der Kontext von this innerhalb des Controllers innerhalb der $http.get Aufruf ändert.

Also meine Frage ist das: Wie erhalten Sie Zugriff auf die Ergebnisse von einem $ http.xxx Anruf mit this anstelle von scope? Ich habe ein paar verschiedene Quellen darüber gelesen, aber die meisten sprechen über die Verwendung von $scope und verspricht. Ich habe keine solche Abdeckung mit this gefunden (oder mit var supplier = this deklariert). Jede Hilfe würde sehr geschätzt werden.

Danke,

+0

Nur ein Heads-up, dass $ http Anrufe in der Regel nicht in Ihre Controller gehören! Extrahieren Sie sie stattdessen zu einem Dienst für Wiederverwendbarkeit, Stabilität und nicht-abhängige Abhängigkeitsinjektion. – Hypaethral

+0

@GrumbleSnatch Danke dafür. Wie gesagt, ich habe gerade angefangen, Angular anzuschauen und habe noch nicht die Zeit gehabt, alle Funktionen und Funktionen durchzusehen, aber das Wissen darüber wird mir wahrscheinlich eine Menge Zeit ersparen, wenn ich sie schließlich entdeckt habe – Doug

Antwort

9

speichern immer eine Variable Bezug auf this so dass Sie nicht Kontext Probleme haben, dann diese Variable anstelle von this gesamten Controller

app.controller('ctrlSuppliers', function($http){ 
    var vm = this; 
    // now can forget using "this" and use variable instead 
    vm.supplierList = {}; 

    $http.get("http://some_url_here") .success(function(response) { 
     // no context issues since "vm" is in scope 
     vm.supplierList = response.records; 
    });    
}); 
+1

Ich bin mir sicher, dass ich diesen Ansatz letzte Nacht ausprobiert habe und es funktionierte nicht für mich, jedoch deklariert 'this' zu einer Variable und referenziert diese Variable jetzt. So einfach - Vielen Dank – Doug

+1

Für jeden, der dies liest, ist der Erfolg jetzt veraltet. Verwenden Sie stattdessen. –

2

Für $ http Sie haben die Möglichkeit, Speichern Ihrer eigenen Objekte in der configObject, die das optionale zweite Argument zu $http.get() ist. Dieses Objekt wird Ihnen dann zur Verfügung gestellt, da es eine Eigenschaft von response ist.

Diese Technik ist besonders nützlich, wenn Sie $ http.get() mehrmals in einer Schleife aufrufen.

1

Ich denke, charlietfl's Antwort ist die richtige, aber denke, eine etwas erweiterte Erklärung könnte hilfreich sein.

"this" verweist in Javascript auf den Kontext des aktuellen Funktionsaufrufs. Wenn Sie auf den Code anschauen, werden Sie sehen, dass dies in zwei Funktionen verwendet -

app.controller('ctrlSuppliers', function($http){ 

    //first use of this - used in the context of the controller function 
    //In this case, this = the controller 
    this.supplierList = {}; 

    $http.get("http://some_url_here") 
      .success(function(response) { 
       //second use of this - used in the context of the http success function callback 
       //this will likely not be the controller. It's value depends on how the caller (the $http framework) invoked the method. 
       this.supplierList = response.records; 
      }) 
      .... 

Da sie zwei verschiedene Funktionen, können sie völlig unterschiedlichen Kontexten, also „das“ auf verschiedene Objekte beziehen (wie Sie gerade erfahren).

Die Standardmethode, um damit umzugehen, besteht darin, den Aufrufkontext der ersten Funktion für die Verwendung in den anderen zu speichern. @ charlietfls Antwort ist ein guter Weg, dies zu erreichen. Ich habe seinen Code als Referenz hinzugefügt.

2

Die this Variable ist in JavaScript schwierig. Wenn die Callback-Funktion ausgeführt wird, wissen Sie nicht, was der this referenziert. Es sei denn, es ist irgendwo dokumentiert.

Sie müssen .bind(this) verwenden, um Ihren eigenen this Wert anzuhängen, der in der Funktion verwendet werden soll.

app.controller('ctrlSuppliers', function($http){ 
    this.supplierList = {}; 
    $http.get("http://some_url_here") 
      .success(function(response) { 
       this.supplierList = response.records; 
      }.bind(this)) 
      .error(function() { 
       this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting Details'}]; 
      }.bind(this)); 
}); 

Siehe bind Handbuch:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

2

Mit Pfeil Funktionen in ECMAScript 6 das Problem mit this ist gesorgt und Sie haben weniger zu geben. Ihr Beispiel würde wie folgt aussehen:

app.controller('ctrlSuppliers', function($http){ 
    this.supplierList = {}; 

    $http.get("http://some_url_here") 
      .success(response => { this.supplierList = response.records; }) 
      .error(() => { this.supplierList = [{supplier_id: 0, supplier_name: 'Error Getting Details'}]; }); 
}); 

das Ergebnis entspricht this auf eine Variable zu speichern, aber prägnanter.

Verwandte Themen