var userRef = new Firebase("https://awesome.firebaseio.com/users/"); var tokenRef = userRef.child(key+'/tokens'); tokenRef.once('value',function(snapshot){ var userTokenSync = $firebase(tokenRef); var userTokens = userTokenSync.$asArray(); console.log(userTokens); console.log(userTokens[0]); for(var i=0,len = userTokens.length; i < len; i++) { console.log(userTokens[i]); } console.log('done'); })
此代码从firebase获取用户的令牌,我只想浏览令牌数组.
这是控制台给我的:
你可以看到,我无法访问数组.你有什么想法吗?
提前致谢.
var userTokens = userTokenSync.$asArray(); console.log(userTokens); console.log(userTokens[0]); for(var i=0,len = userTokens.length; i < len; i++) { console.log(userTokens[i]); } console.log('done');
该片段的第一行开始从Firebase载入数据.但是加载可能需要一些时间.而且由于浏览器不想阻止它,所以继续执行脚本.
当浏览器执行你的console.log(userTokens);数据最有可能尚未加载.所以它只是将对象作为占位符打印到控制台.
当它到达for循环时,数据可能已经还可能还没有从Firebase加载.
在某些时候,您点击了记录的用户名称旁边的箭头.当时数据已从Firebase加载,控制台显示最新数据.
该解决方案由AngularFire以承诺的形式提供. AngularFire承诺在将来的某个时候为您提供数据.如果你有一段代码只能在数据加载时执行,你可以这样写:
var userTokens = userTokenSync.$asArray(); console.log(userTokens); console.log(userTokens[0]); userTokens.$loaded(function(userTokens) { for(var i=0,len = userTokens.length; i < len; i++) { console.log(userTokens[i]); } console.log('done'); }); console.log('at last line,but not done yet');
更新
注意上面是一个坏的例子,何时使用$loaded.由于$loaded将仅触发一次,它将只记录数组的初始内容.如果您只是想/看到/数据何时加载,则惯用方法是将userTokens添加到范围中:
$scope.userTokens = userTokens;
并将其添加到您的视图/ HTML:
<pre>{{ userTokens | json }}</pre>
AngularFire现在将以任何方式监视userTokens何时加载或修改,如果发生这种情况,AngularFire将会更新视图.
还可以看到这些:
> Firebase,AngularJS and GeoFire – wait for response from factory
> Firebase angularfire child.$asObject give properties undefined
> angularfire – why can’t I loop over array returned by $asArray?
> Passing variable in parent scope to callback function
> Trying to get child records from Firebase
嗯…我们得到这个问题很多