2015-05-27 71 views
1

我試圖從URL中獲取一些數據,將其存儲在一個變量中並將其返回給我的控制器。但問題是,在變量已經被返回給控制器(調用該函數)後,處理來自URL的數據。我打電話我Service.js服務URL 這裏是我正在做它:如何將服務URL數據傳遞給控制器​​調用的函數

var demoService = angular.module('demoService', []).service('myService', function($http, $q) { 
    var gaugeData = { 
     maxValue: 5000, 
     animationSpeed: 100, 
     val: 5000 
    }; 

    console.log(gaugeData); 

    var deferred = $q.defer(); 
    $http.get('http://myurl').then(function(data) { 
     console.log(data.data.Tweets[3].FAVOURITE_COUNT); 
     var gaugeData = { 
      maxValue: 5000, 
      animationSpeed: 100, 
      val: data.data.Tweets[3].FAVOURITE_COUNT 
     }; 
     deferred.resolve(gaugeData); 
     console.log(gaugeData); 
    }); 

    this.get = function() { 
     deferred.promise.then(function(data) { 
      console.log(data); 
      gaugeData.val = data.val; 
     }); 
     return gaugeData; 
    }; 

    function sleep(milliseconds) { 
     var start = new Date().getTime(); 
     for (var i = 0; i < 1e7; i++) { 
      if ((new Date().getTime() - start) > milliseconds) { 
       break; 
      } 
     } 
    } 

    this.list = function() { 
     return gaugeData; 
    }; 

}); 

控制器預計,在相同的形式gaugeData對象數據,但由於gaugeData被填滿服務數據在該值已經返回後,控制器顯示沒有對象(undefined)。控制檯看起來像這樣:

Object {maxValue: 5000, animationSpeed: 100, val: 5000} 
    controllers.js:202 $…t.l.$…w.a.$…e.$$ChildScope {$$childTail: null, $$childHead: null, $$nextSibling: null, $$watchers: null, $$listeners: Object…} (console.log); from controller 
    app.js:15 TypeError: Cannot read property 'maxValue' of undefined (since an empty value is passed) 
     1566 
    services.js:137 Object {maxValue: 5000, animationSpeed: 100, val: 1566} 
    services.js:144 Object {maxValue: 5000, animationSpeed: 100, val: 1566} 

顯然,控制首先進入該服務,然後在正在處理的URL,則控制跳轉到控制和取空值並在此之後已經發生的URL被處理並gaugeData獲得來自服務URL的值。 我試圖做這個沒有承諾和推遲。我只是使用$http.get(url).success(function(){code});

如何將我的URL數據傳遞給變量並在正確的時間將其正確傳遞給控制器​​?

而且,這裏是我的控制器代碼段我打電話的服務功能:

console.log($scope); 
return $scope.gaugeHome ={ 
     gaugeData: 
      myService.get(), ..... 
+0

'this'裏面的'then'是窗口對象,這是嚴格模式下的錯誤 - 以嚴格模式運行你的代碼:) –

+0

@BenjaminGruenbaum - 作者在'then'裏面並沒有'this'。剛剛有縮進(現在修復)。 ;-) –

回答

1
  1. 保鮮膜別在新的延期現有的承諾;這是一種反模式。 $http已經返回一個承諾,您可以通過return來修改處理程序的新承諾或值。

  2. 您無法返回異步操作結果的同步值。這是一個根本的矛盾。如果您需要返回最終會設置爲某個值的內容,那麼這就是承諾的全部要點。您的服務應該返回一個承諾,然後您的控制器將打電話給then

  3. 您的sleep功能令人擔憂。看起來你正在使用一個繁忙的循環來......做什麼?將CPU掛起一段時間?爲什麼?爲什麼不只是$timeout

以下是您的服務的一個版本:A)一次獲取資源,B)將其存儲在承諾中,C)讓消費者(控制器)請求承諾。控制器將不得不打電話then來決定如何處理結果。

如果您希望您的服務能夠更新資源,可以將承諾生成包裝在一個函數中,該函數將再次運行fetch並返回一個新的承諾。目前尚不完全清楚你的最終目標是什麼,所以我沒有表現出這種方法。現在

var demoService = angular.module('demoService', []).service('myService', function($http, $q) { 

    var gaugePromise = $http.get('http://myurl').then(function(response) { 
     var updatedGuageData = { 
      maxValue: 5000, 
      animationSpeed: 100, 
      val: response.data.Tweets[3].FAVOURITE_COUNT 
     }; 
     return updatedGuageData; 
    }); 

    this.get = function() { 
     return gaugePromise; 
    }; 

}); 

,你可以有服務緩存值作爲同步對象(沿着你嘗試一下線),而當你異步得到它,更新緩存的副作用(如你在做)。但是,每次執行異步更新時,只有使用回調或承諾處理程序纔會知道它已成功(或失敗),這會使緩存的同步值無意義 - 爲什麼不使用結果直接的異步?簡單得多。

相關問題