2016-07-22 136 views
1

我正在編寫此函數以在我的角度應用程序中用於評估ng-repeat列表中的ng-src。我需要使調用同步,以便每次調用該函數時該值都是正確的。問題是:從Firebase存儲器返回下載URL的函數

爲什麼這個代碼返回值:

var storage = firebase.storage(); 
var returnVal; //causes sync issues 
var getImageUrl = function (time) { 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     returnVal = url; 
    }); 
    return returnVal; 
}; 

但是,這並不工作:

var storage = firebase.storage(); 
var getImageUrl = function (time) { 
    var returnVal; //so that this is specific to the function 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     returnVal = url; //I simply want to return the value of 'url' 
    }); 
    return returnVal; 
}; 

任何想法如何,我可以讓getImageUrl()函數返回來自.then的網址?

這是文檔鏈接:https://firebase.google.com/docs/storage/web/download-files

最後我會變成一個$範圍功能使用與此類似:

<div ng-repeat="message in messages"> 
    <img ng-src="{{ getImageUrl(message.time) }}"> 
</div> 
+0

參見https://stackoverflow.com/questions/42956250/get-download-url-from-file-uploaded-with-cloud -functions換火力 – Kato

回答

2

你的函數的變化都不永遠不會返回一個值,不是nullundefined。您正在執行一個異步調用,在繼續執行下面的代碼之前不會等待的結果。例如:

var storage = firebase.storage(); 
// Execute (1) 
var getImageUrl = function (time) { 
    // Execute (2) 
    var returnVal; 
    // Execute (3) 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     // Execute (unknown) 
     returnVal = url; 
    }); 
    // Execute (4) 
    return returnVal; 
}; 
// Execute (unknown times) 

你不知道什麼時候異步調用將返回的數據,但它總是會後return returnVal;因此returnVal爲空。

我建議這樣的:

$scope.images = []; 
$scope.messages = { // whatever }; 
for (m in $scope.messages) { 
    storage.ref('images/' + time + '.jpg').getDownloadURL().then(function (url) { 
     // Might need $scope.$apply(function() {}) surrounding 
     $scope.images.push(url); 
    }); 
} 

然後在您的視圖:

<div ng-repeat="image in images"> 
    <img ng-src="{{ image }}"> 
</div> 

的時間這一切加載是依賴於$scope.messages大小。如果數量很大,我建議更改您的數據結構,這樣您就不必多次調用數據庫。

0

theblindprophet的答案包含了一個很好的解釋,說明爲什麼你現在的代碼無法正常工作和工作的解決方案。

作爲替代方案,您可以簡單地返回getDownloadURL()返回的所謂承諾。我沒有測試過,但期望Angular自動選擇承諾。

var storage = firebase.storage(); 
var getImageUrl = function (time) { 
    return storage.ref('images/' + time + '.jpg').getDownloadURL(); 
}; 

而在你的HTML你只是保持:

<div ng-repeat="message in messages"> 
    <img ng-src="{{ getImageUrl(message.time) }}"> 
</div>