监听器上的Angular$在回调时返回未定义的数据值
Firebase - Angular $on listener returns data undefined value on callback
我正在尝试从firebase中获取一些数据,我正在使用angular firebase插件。我在检查器中仔细检查了调试,url是正确的。它会返回,这意味着url是正确的,但回调的参数是未定义的。
我正在使用loaded,因为我需要它发射一次。我尝试了有价值但有羞耻感的东西。
我想我今天已经把所有的精力都用在了这件事上,所以再发表一个意见就好了。
附言:我真的很奇怪他们为什么不使用承诺而不是回调。
来自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;
};
我在这里添加所有代码是为了让你更好地了解我要做的事情。
我的fb.match.service的完整代码
'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;
}
};
}]);
提前谢谢。干杯,玩得开心!
好了,终于"找到"了解决方案。感谢kato提醒我检查我的版本。
目前0.7.2版本的预览版对我来说很有效。问题是它还没有在bower上,我认为我在bower更新时有最新版本。这是错误的。
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的更新效果更好,因为该项目的进展似乎比bower注册表快得多。
干杯,玩得开心。
我在angularfire.js 中用一个小黑客修复了这个问题
$on处理程序中的第336ish行
336. callback();
变更
336. callback(self._snapshot);
_wrapTimeout函数末尾的第587ish行添加
587. //hack to preserve the snapshot from the timeout wipeouts
if ( evt === "loaded" ) {
self._snapshot = param;
}
我希望这对你现在有所帮助。我会设法找到一个合适的解决方案。
需要记住的另一个想法是
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(match的DB引用)与我期望从firebase中得到的对象进行合并。
"13131314141"{
"playerA" : {
"location" : {
"lat" : 51.6021821,
"long" : "-02582276"
},
"type" : "monster"
}
}
你实际上可以从中找到解决方案。但是,如何将回调中的结果用作promise deferred.resolve呢?
我可以理解他们这样做是为了能够进行
$scope.match=$matchDB$on('loaded',function(){});
但这不符合我的目的,即将firebase与我的控制器解耦,我真的不认为这实际上是一个巧妙的解决方案。
请不要接受这是一个解决方案,因为它不是一个真正的解决方案。你可以破解你的方法使其成为一个,但可能有更好的方法来做到这一点,或者至少这个项目还太年轻,很快就会有合适的解决方案。
- 这.SOMETHING 总是返回未定义的 - extjs
- React+Meteor:this.ops返回未定义
- 解析-为什么user.getSessionToken()返回未定义的结果
- Javascript函数返回未定义
- JavaScript-获取数据属性的值返回未定义的值
- .val()返回未定义的.text返回随机代码
- 为什么innerHTML返回“未定义”
- "这个“;正在返回未定义的
- 谷歌地图:函数返回未定义的值在console.log中运行良好
- Javascript json返回未定义
- importScripts在web工作程序中返回未定义的
- 访问嵌套 json 对象的属性将返回未定义
- NativeAppEventEmitter返回未定义的
- 我的函数返回“未定义”
- 新手Javascript函数返回未定义的石头剪刀游戏
- Nodejs模块函数返回未定义的,而不是异步的
- .getElementById在.createTextNode中返回未定义
- javascript函数不返回未定义的值
- Typeahead的Javascript类型返回未定义
- Javascript可见元素返回未定义