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