我试图从firebase获取一些数据,我使用的是角火力插件。我在检查器中仔细检查了调试,url是正确的。它回应,这意味着url是正确的,但回调的参数是未定义的。
我使用已加载因为我需要它才能触发一次。我尝试了价值,但感到羞耻。
我想我今天已经耗尽了所有的精力,所以第二种意见会很棒。
P.S。我真的很想知道他们为什么不使用承诺而不是回调。
来自angular + firebase工厂的 var seekMatch = function(player) {
var deferred = $q.defer();
angular.forEach(matches.$getIndex(), function(matchId) {
var matchRef = firebaseRef('matches/' + matchId); // <-- double checked, the url sends me to the correct firebase record
var matchDB = $firebase(matchRef);
matchDB.$on('loaded', function(data) {
console.log(data); // <----- return's undefined
if (matchMakingFormula(data.playerA, player)) {
if (!match) {
match = data;
deferred.resolve(match);
}
}
});
});
return deferred.promise;
};
我在这里添加了所有代码,以便您更好地了解我尝试做的事情。
'use strict';
angular.module('angularfireApp')
.factory('FBmatchService', ['$rootScope' , '$q', '$firebase', 'firebaseRef',
function ($rootScope, $q, $firebase, firebaseRef) {
// Service logic
var matchesRef = firebaseRef( '/matches/' );
var matches = $firebase(matchesRef);
var match = null;
var matchMakingFormula = function (playerA , playerB) {
return playerA.type !== playerB.type
&& distanceFormula( playerA.location.lat , playerA.location.long, playerB.location.lat , playerB.location.long ) < 1
};
var distanceFormula = function (lat1 , lon1 , lat2, lon2) {
var R = 6371; // km
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad();
var lat1 = lat1.toRad();
var lat2 = lat2.toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
};
var getMatch = function (matchId) {
match = matches.$getIndex(matchId);
return match;
};
var seekMatch = function ( player ) {
var deferred = $q.defer();
angular.forEach(matches.$getIndex() , function (matchId){
var matchRef = firebaseRef( 'matches/'+matchId );
var matchDB = $firebase( matchRef );
matchDB.$on('loaded',function (data) {
console.log(data);
if (matchMakingFormula(data.playerA , player)) {
if (!match) {
match = data;
deferred.resolve(match);
}
}
});
});
return deferred.promise;
};
// Public API here
return {
get: function (matchId) {
return getMatch(matchId);
},
seek: function (points) {
return seekMatch(points);
//return match.promise;
},
new: function (points) {
//return match.promise;
},
join: function (match) {
//return match;
}
};
}]);
提前致谢。干杯,玩得开心!
答案 0 :(得分:1)
好的,最后&#34;发现&#34;解决方案。感谢kato提醒我检查我的版本。
当前版本0.7.2预览适用于我。事情是,这还没有凉亭,我认为我从凉亭更新时有最新版本。这是错的。
collection.$child( matchId ).$on('loaded' , function(match){ //<---- match now returns the proper object but also null or {} empty object sometimes if empty.
if (match) {
if (valid(match)){ //<-- so you need to validate the output not just !match
deferred.resolve(match);
}
else
{
deferred.reject('invalid');
}
}
else
{
deferred.reject('no match');
}
});
在使用端点进行恢复和错误捕获之前,无论哪种方式验证端点都是一个好主意。
更好地从github更新,因为该项目似乎比它的凉亭注册表更快。
干杯,玩得开心。
答案 1 :(得分:0)
另一个想到要记住的是这个
matchDB.$on('loaded', function(data) {
console.log(matchDB); // <--- notice what is going on here
if (matchMakingFormula(data.playerA, player)) {
if (!match) {
match = data;
deferred.resolve(match);
}
}
});
返回
matchDB: Object
$add: function (item) {
$auth: function (token) {
$bind: function (scope, name) {
$child: function (key) {
$getIndex: function () {
$off: function (type, callback) {
$on: function (type, callback) {
$remove: function (key) {
$save: function (key) {
$set: function (newValue) {
$transaction: function (updateFn, applyLocally) {
playerA: Object // <---- notice this. it was the content of the object in firebase
__proto__: Object
哪个是完全疯狂的...... 它实际上是将matchDB(匹配的DB引用)与我期望从firebase中获得的对象合并。
"13131314141"{
"playerA" : {
"location" : {
"lat" : 51.6021821,
"long" : "-02582276"
},
"type" : "monster"
}
}
你实际上可以解决这个问题。但是如何在回调中将结果用作promise deferred.resolve?
我能理解他们这样做是为了能够做到
$ scope.match = $ matchDB。$ on(&#39; loaded&#39;,function(){});
但这并不符合我的目的,即将firebase与我的控制器分离,我并不认为它实际上是一个简洁的解决方案。
请不要接受此作为解决方案,因为它不是真正的解决方案。你可以破解你的方式,但可能有更好的方法,或者至少项目太年轻,很快就会有适当的解决方案。
答案 2 :(得分:0)
我用angularfire.js中的一个小黑客修复了这个问题
$ on处理程序中的行336ish
336. callback();
随
改变336. callback(self._snapshot);
在_wrapTimeout函数add
结尾处的第587行 587. //hack to preserve the snapshot from the timeout wipeouts
if ( evt === "loaded" ) {
self._snapshot = param;
}
我希望这对你现在有所帮助。我会尽力为此找到合适的解决方案。