angularfire:使用$ asArray()从我的工厂获取Firebase数组时遇到问题

时间:2014-10-30 20:53:55

标签: arrays angularjs firebase angularfire

我有一个从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);
}());

2 个答案:

答案 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。您可能需要对工厂代码的其余部分进行一些调整。