2

我試圖從Firebase數據庫中檢索數據,並從Firebase存儲中檢索相應的圖片。問題是,我的觀點不想用數據更新自己。更新後的範圍變量未顯示在視圖中。承諾無效

如果我試圖簡單地從我的數據庫中獲取數據,它可以很好地工作。一旦我添加獲取圖片的功能(需要稍微長一些),它看起來像我的視圖只是立即查看範圍變量,並不等待$ scope.friendsinfo更新。我認爲我在承諾中做錯了什麼,應該使用$ q,但我不知道具體如何。誰能告訴我什麼是最好的方式去做這件事?非常感謝!

var friendsRef = firebase.database().ref('friendships/' + firebase.auth().currentUser.uid); 

$scope.friends = $firebaseArray(friendsRef); 

$scope.friendsinfo = []; 

$scope.$watch('friends', function() { 
    var newfriends = $scope.friends; 
    var newfriendsinfo = []; 

    for(var i = 0; i < newfriends.length; i++){ 
     var ref = firebase.database().ref('users/' + newfriends[i].$id); 
     var profilePicRef = firebase.storage().ref("profilepictures/" + newfriends[i].$id + "/profilepicture"); 
     var picPromise = fetchPicture(profilePicRef); 

     var newfriendid = newfriends[i].$id; 
     var newfriendagreed = newfriends[i].agreed; 

     picPromise.then(function(data){ 
      ref.once('value', function(snapshot){ 
       newfriendsinfo.push({ 
        id: newfriendid, 
        name: snapshot.val().name, 
        email: snapshot.val().email, 
        agreed: newfriendagreed, 
        profilepicture: data //This is the functionality that causes my view to not display the updated $scope.friendsinfo because it takes too long. 
       }); 
      }); 
     }); 
    } 
    $scope.friendsinfo = newfriendsinfo; 
    alert($scope.friendsinfo.length); 
}, true); 

function fetchPicture(ref){ 
    return ref.getDownloadURL().then(function(url) { 
     return url; 
    }).catch(function(error) { 
     alert("error"); 
    }); 
} 

回答

0

我沒有得到你的密碼正確,但張貼的代碼,你會以指導如何使用承諾與決心的辦法:

function asyncGreet(name) { 
    var deferred = $q.defer(); 

    setTimeout(function() { 
    deferred.notify('About to greet ' + name + '.'); 

    if (okToGreet(name)) { 
    deferred.resolve('Hello, ' + name + '!'); 
    } else { 
     deferred.reject('Greeting ' + name + ' is not allowed.'); 
    } 
    }, 1000); 

    return deferred.promise; 
} 

var promise = asyncGreet('Robin Hood'); 
promise.then(function(greeting) { 
    alert('Success: ' + greeting); 
}, function(reason) { 
    alert('Failed: ' + reason); 
}, function(update) { 
    alert('Got notification: ' + update); 
}); 
0

如果有誰需要的解決方案,在這兒呢。結果發現問題主要是由於等待for循環完成而導致的,每個項目都等待另一個函數完成。這是我能夠解決它的方式。這可能不是最佳的,但它現在會做:)

var friendsRef = firebase.database().ref('friendships/' + firebase.auth().currentUser.uid); 

$scope.friends = $firebaseArray(friendsRef); 

$scope.friendsinfo = []; 

$scope.$watch('friends', function() { 
    var newfriends = $scope.friends; 

    asyncUpdateFriendsInfo(newfriends).then(function(newlist){ 
     $scope.friendsinfo = newlist; 
    }); 
}, true); 

function fetchPicture(ref){ 
    return ref.getDownloadURL().then(function(url) { 
     return url; 
    }).catch(function(error) { 
     alert("error"); 
    }); 
} 

function asyncUpdateFriendsInfo(newfriends){ 
    var deferred = $q.defer(); 
    var newfriendsinfo = []; 

    for(var i = 0; i < newfriends.length; i++){ 
     var ref = firebase.database().ref('users/' + newfriends[i].$id); 
     var profilePicRef = firebase.storage().ref("profilepictures/" + newfriends[i].$id + "/profilepicture"); 
     var picPromise = fetchPicture(profilePicRef); 

     var newfriendid = newfriends[i].$id; 
     var newfriendagreed = newfriends[i].agreed; 

     picPromise.then(function(data){ 
      ref.once('value', function(snapshot){ 
       newfriendsinfo.push({ 
        id: newfriendid, 
        name: snapshot.val().name, 
        email: snapshot.val().email, 
        agreed: newfriendagreed, 
        profilepicture: data 
       }); 
      }).then(function(){ 
       if (newfriendsinfo.length == newfriends.length){ 
        deferred.resolve(newfriendsinfo); 
       } 
      }); 
     }); 
    } 

    return deferred.promise; 
}