我有一个从Firebase获取数据的工厂,我希望我的控制器能够访问它。但是,当我在我的控制器中调试数据时,它不是我期望它的数组[10],而是添加了键0,1,2,... 10,$$的数组, $$错误,$$移动,......等等。但是,当我跳过使用工厂,并在我的firebase ref中直接在我的控制器中使用$ asArray()方法时,它很好地显示为数组[10]
在我的工厂,这就是它的样子......
var listingsref = new Firebase("https://something.firebaseio.com");
var sync2 = $firebase(listingsref);
var products = sync2.$asArray();
factory.getProducts = function(){
return products;
};
控制器
$scope.products = marketFactory.getProducts();
我的控制器中的console.log($ scope.products)应该是Array [10],但它是一个带有数据的数组+更多的$$方法。有谁知道发生了什么?感谢
编辑:完整工厂文件
(function(){
var marketFactory = function($firebase){
var listingsref = new Firebase("https://something.firebaseio.com");
var sync2 = $firebase(listingsref);
var products = sync2.$asArray();
var factory = {};
factory.getProducts = function(){
console.log(products);
return products;
};
factory.getProduct = function(productId){
for(var x = 0; x<products.length ;x++){
if(productId == products[x].id){
return {
product:products[x],
dataPlace:x
};
}
}
return {};
};
factory.getNextProduct = function(productId, e){
var currentProductPlace = factory.getProduct(productId).dataPlace;
if (e=="next" && currentProductPlace<products.length){
return products[currentProductPlace+1];
}
else if(e=="prev" && currentProductPlace>0){
return products[currentProductPlace-1];
}
else{
return {};
}
};
factory.componentToHex = function(c){
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
};
factory.rgbToHex = function(r,g,b){
return "#" + factory.componentToHex(r) + factory.componentToHex(g) + factory.componentToHex(b);
};
factory.hexToRgb = function(hex) {
if(hex.charAt(0)==="#"){
hex = hex.substr(1);
}
var bigint = parseInt(hex, 16);
var r = (bigint >> 16) & 255;
var g = (bigint >> 8) & 255;
var b = bigint & 255;
return r + ", " + g + ", " + b;
};
factory.parseRgb = function(rgb){
rgb = rgb.replace(/\s/g, '');
var red = parseInt(rgb.split(',')[0]);
var green = parseInt(rgb.split(',')[1]);
var blue = parseInt(rgb.split(',')[2]);
return {
r:red,
g:green,
b:blue
};
};
return factory;
};
marketFactory.$inject = ['$firebase'];
angular.module('marketApp').factory('marketFactory', marketFactory);
}());
答案 0 :(得分:7)
此代码段获得同步的AngulareFire array产品:
var products = sync2.$asArray();
AngularFire文档在这一点上有点偏离:从$asArray()
返回的不是数组,而是数组的承诺。在将来的某个时刻,您的products
变量将包含一个数组。这样做是因为从Firebase下载阵列数据可能需要(相当)一段时间。它不是在下载数据时阻塞你的代码/浏览器,而是返回一个包装器对象(称为 promise )并继续。
这样的承诺对AngularJS来说已经足够了:如果你只是将products
绑定到范围而ng-repeat
绑定到范围,那么你的视图就会显示所有产品。这是因为AngularFire幕后让AngularJS知道数据何时可用,然后Angular重新绘制视图。
但你说:
我的控制器中的
console.log($scope.products)
应为Array [10]
这就是你错的地方。虽然AngularFire确保其$asArray()
承诺与AngularJS一起正常工作,但它对console.log
没有做同样的事情。因此,您的console.log
代码会在从Firebase下载数据之前运行。
如果您真的必须记录产品,您应该等到承诺得到解决。您可以使用以下结构:
products.$loaded().then(function(products) {
console.log(products);
});
当您按照此代码段进行编码时,您的产品数据将在console.log
运行时下载。
请注意,该对象仍然有额外的辅助方法,例如$add
。这是正常的,也对数组有效。有关方法的详细信息,以及如何使用这些方法的详细信息,请参阅the documentation for FirebaseArray。
答案 1 :(得分:0)
所以我在http://plnkr.co/M4PqojtgRhDqU475NoRY的plnkr中编辑了代码。
主要区别如下:
// Add $FirebaseArray so we can extend the factory
var marketFactory = function($firebase, $FirebaseArray){
var listingsref = new Firebase("https://something.firebaseio.com");
// Actually extend the AngularFire factory and return the array
var MarketFactory = $FirebaseArray.$extendFactory(factory);
return function() {
var sync = $firebase(listingsref, {arrayFactory: factory});
return sync.$asArray();
};
有关扩展AngularFire条目的更多信息,请查看https://www.firebase.com/docs/web/libraries/angular/guide.html#section-extending-factories。您可能需要对工厂代码的其余部分进行一些调整。