2015-05-14 16 views
7

Jestem całkiem nowy dla całego świata AngularJS i jak to działa, jednak staram się, aby działał zgodnie z oczekiwaniami. Wiem, że to ma coś wspólnego ze sposobem, w jaki używam $http.get() i próbuję przypisać zmienne z powrotem do kontrolera, ale po prostu nie mogę tego rozgryźć.

Korzystanie $scope zamiast this mogę dostać pracy, jednak jeśli to możliwe, wolałbym używać this więc mogę użyć „kontroler jako”

kod:

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'}];}); 
}); 

z tego Na przykład nie mogę uzyskać dostępu do żadnych wyników z żądania $http.get z poziomu supplierList na stronie HTML (tzn. {{ supplier.supplierList[0].supplier_name }} nie wyświetla żadnych wyników)

Wiem, że jeśli zmienię kontroler na $scope, będę mógł uzyskać dostęp do tych danych (chociaż nie będę używać tego samego formatu co powyżej) i wiem również, że dane są zapełniane za pomocą console.log(this.supplierList) wewnątrz połączenia .success.

Wiem również, że powodem jego działania jest to, że kontekst this zmienia się z poziomu kontrolera na wywołanie $http.get.

Moje pytanie brzmi następująco: Jak uzyskać dostęp do wyników z połączenia $ http.xxx za pomocą this zamiast scope? Czytałem kilka różnych źródeł na ten temat, ale większość mówi o użyciu $scope i obietnic. Nie znalazłem żadnej z tych okładek, używając this (lub deklarując ją jako var supplier = this). Każda pomoc byłaby bardzo cenna.

Dzięki,

+0

Po prostu heads-up, że wywołania $ http zazwyczaj nie należą do kontrolerów! Zamiast tego wyodrębnij je do usługi, aby uzyskać ponowne wykorzystanie, stabilność i nieszkodliwy zastrzyk zależności. – Hypaethral

+0

@ GrumbleSnatch Dzięki za to. Jak już powiedziałem, dopiero zacząłem patrzeć na Angulara i nie miałem czasu przejrzeć wszystkich funkcji i funkcji, jednak wiedza o tym teraz prawdopodobnie zaoszczędzi mi wiele czasu na torze, kiedy w końcu je odkryłem – Doug

Odpowiedz

9

przechowywać zawsze zmienny odniesienie do this tak, że nie masz problemów kontekstowych, a następnie użyć tej zmiennej zamiast this całym kontrolera

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

Jestem pewna, że ​​próbowałem tego podejścia ostatniej nocy i nie działało to dla mnie, jednak deklarując "to" zmiennej i odwołując się do tej zmiennej, teraz działa. Tak proste - wielkie dzięki – Doug

+1

Dla każdego, kto to czyta, sukces jest teraz przestarzały. Zamiast tego użyj .then. –

2

Dla $ http masz możliwość przechowywania własnych obiektów w configObject, który jest opcjonalnym drugim argumentem dla $http.get(). Obiekt ten jest następnie udostępniany użytkownikowi, ponieważ jest to własność response.

Ta technika jest szczególnie użyteczna, jeśli wywołujesz wiele razy funkcję http.get() w pętli.

1

Myślę, że odpowiedź charlietfl jest poprawna, ale myślę, że pomocne może być nieco rozszerzone wyjaśnienie.

"this" w javascript odnosi się do kontekstu bieżącego wywołania funkcji. Jeśli spojrzeć na kod, zobaczysz, że ten jest używany w dwóch funkcji -

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; 
      }) 
      .... 

Ponieważ są dwie różne funkcje, mogą mieć zupełnie różne konteksty, więc „to” będzie odnosić się do różnych obiektów (tak, jak tego doświadczasz).

Standardowym sposobem rozwiązania tego problemu jest zapisanie kontekstu wywołania pierwszej funkcji do użycia w innych. Odpowiedź @ charlietfl jest dobrym sposobem na osiągnięcie tego. Dodałem jego kod w celach informacyjnych.

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

    $http.get("http://some_url_here") 
      .success(function(response) { vm.supplierList = response.records;}) 
}); 
2

Zmienna this jest trudna w JavaScript. Gdy funkcja wywołania zwrotnego zostanie wykonana, nie będziesz wiedział, do czego odnosi się this. Chyba że gdzieś jest udokumentowane.

Musisz użyć .bind(this), aby dołączyć własną wartość this do użycia w funkcji.

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)); 
}); 

patrz instrukcja obsługi wiążą:

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

2

Dzięki funkcji strzałek dostępnych w ECMAScript 6 problem z this jest pod opieką i masz mniej pisać. Wasz przykład będzie wyglądać następująco:

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'}]; }); 
}); 

wynik jest równoważna przechowywania this do zmiennej, ale bardziej zwięzły.

Powiązane problemy