簡體   English   中英

AngularJS,如何使用服務捕獲HTTP數據並將其綁定到我的控制器?

[英]AngularJS, how do I use a service to capture HTTP data and bind it to my controller?

我有一個非常好的API調用,但是我想在多個控制器上使用它,因此我將其移到了它自己的服務中。 我遇到了看起來像是經典的Scope問題或對Angular的摘要周期的誤解。

'use strict';
myApp.factory('Stuff',['$http', function ($http) {
  var Stuff = {};
  Stuff.data = {};
  Stuff.api = 'http://localhost:8080/api/';
  Stuff.getStuff = function() {
    var http_stuff_config = {
      method: 'GET',
      url: Stuff.api + 'stuff/'
    };
    $http(http_stuff_config).then(function successCallback(response) {
      Stuff.data = (response.data);
      console.log(Stuff.data); // Returns populated object. 
    },function errorCallback(response) {
      console.log(response.statusText);
    });
  };
  Stuff.getStuff();
  console.log(Stuff.data); // Returns empty object.
  return Stuff;
}]);

myApp.controller('appController', ['$scope','Stuff',function($scope,Stuff) {
  $scope.stuff = Stuff;
  console.log($scope.stuff.data); // Returns empty object.
  $scope.stuff.getJobs();
  console.log($scope.stuff.data); // Returns empty object.
}]);

這是個大提示。 以上的基本輸出,依次是...

  1. 空對象(調用方法后在使用中)
  2. 空對象(在控制器中,調用方法之前)
  3. 空對象(在調用方法后的控制器中)
  4. 填充的對象(在從服務執行方法中)
  5. 填充的對象(在從控制器執行的方法中)

因此,在getStuff()方法的范圍和Angular的操作順序之間的某個地方,我正在做一些非常愚蠢的事情。 先感謝您。

您需要在服務上添加退貨,否則承諾將不會退還給控制器。 僅將返回值存儲在服務中,而不將結果返回給控制器不是一個好習慣。

這被認為是不好的做法,因為任何時候更新服務上的數據時,每個人都需要向服務應用$scope.$watch以查找更新。 在大型應用程序中,這可能會非常昂貴。

最好的主意是將數據返回給調用控制器(如果不需要緩存它,我們稍后可以討論),然后讓控制器通過promise service.getthing().then(function(result){});訪問它service.getthing().then(function(result){});

myApp.factory('Stuff',['$http', function ($http) {
  var Stuff = {};
  Stuff.data = {};
  Stuff.api = 'http://localhost:8080/api/';
  Stuff.getStuff = function() {
    var http_stuff_config = {
      method: 'GET',
      url: Stuff.api + 'stuff/'
    };
    return $http(http_stuff_config).then(function successCallback(response) {
      return response.data;
      console.log(Stuff.data); // Returns populated object. 
    },function errorCallback(response) {
      console.log(response.statusText);
    });
  };
  Stuff.getStuff();
  console.log(Stuff.data); // Returns empty object.
  return Stuff;
}]);




myApp.controller('appController', ['$scope','Stuff',function($scope,Stuff) {
  $scope.stuff = Stuff;
  console.log($scope.stuff.data); // Returns empty object.
  $scope.stuff.getJobs().then(function(result) {$scope.stuff = result; console.log(result);});
  console.log($scope.stuff.data); // Returns empty object.
}]);

記住$scope.stuff.getJobs()是異步的

(這意味着您實際上無法在下一行調用console.log($scope.stuff.data)並獲取數據)

現在,如果您有一個視圖,並且帶有<span ng-bind="stuff.data.property"> ,則可以看到它正常工作,因為異步功能完成后,視圖將自動更新。 (這是角的一部分)

我建議您不要將結果存儲在服務本身(Stuff.data)中。 只需在getStuff函數中返回數據,然后讓appController的作用域存儲數據即可。

您需要了解,當您運行$ http時,它正在發出AJAX請求。 因此它不會立即返回結果。

因此,如果您嘗試使用來自$ scope.stuff.getJobs();的數據。 調用此功能后,您可能一無所獲。

您應該做的是讓Stuff.getJobs()返回一個promise,並使用promise.then(您自己的成功處理程序)正確處理返回的響應。

我已經整理了一下您的代碼。 以下是從Yahoo Weather API檢索數據的代碼的運行示例。

您可以在CODEPEN上玩它。

的HTML:

<div ng-app="myApp" ng-controller="appController">
  <p>{{data}}</p>
</div>

JS:

var myApp = angular.module("myApp", []);

myApp.factory('Stuff',['$http', function ($http) {
  var Stuff = {};
  Stuff.data = {};
  //sample yahoo weather api
  Stuff.api = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22nome%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys';

  Stuff.getData = function() {
    var http_stuff_config = {
      method: 'GET',
      url: Stuff.api + 'stuff/'
    };
    return $http(http_stuff_config);
  };

  return Stuff;
}]);

myApp.controller('appController', ['$scope','Stuff',function($scope,Stuff) {
  $scope.data = "$http service not ran";

  var uncompletedAjaxCall = Stuff.getData();
  uncompletedAjaxCall.then(
    function(responseData){
      $scope.data = responseData;
    }, 
    function(errorMsg){}
  );

}]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM