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

pyr*_*ace 1 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;
};
Run Code Online (Sandbox Code Playgroud)

调节器

$scope.products = marketFactory.getProducts();
Run Code Online (Sandbox Code Playgroud)

我的控制器中的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);
}());
Run Code Online (Sandbox Code Playgroud)

Fra*_*len 7

此代码段获取同步的AngulareFire产品数组:

var products = sync2.$asArray();
Run Code Online (Sandbox Code Playgroud)

AngularFire文档在这一点上有点偏离:你从中获得的$asArray()不是数组,而是数组的承诺.在将来的某个时刻,您的products变量将包含一个数组.这样做是因为从Firebase下载阵列数据可能需要(相当)一段时间.它不是在下载数据时阻塞你的代码/浏览器,而是返回一个包装器对象(称为promise)并继续.

这样的承诺对于AngularJS来说已经足够了:如果你只是绑定products到范围和ng-repeat它上面,你的视图将显示所有产品就好了.这是因为AngularFire幕后让AngularJS知道数据何时可用,然后Angular重绘视图.

但你说:

console.log($scope.products) 在我的控制器应该是数组[10]

那是你错的地方.虽然AngularFire确保其$asArray()承诺与AngularJS一起正常工作,但它并没有做同样的事情console.log.因此,您的console.log代码会在从Firebase下载数据之前运行.

如果您确实必须记录产品,则应等到承诺得到解决.你这个用以下结构:

products.$loaded().then(function(products) {
    console.log(products);
});
Run Code Online (Sandbox Code Playgroud)

当您像这个代码段一样对其进行编码时,您的产品数据将在时间console.log运行时下载.

请注意,该对象仍将具有额外的辅助方法,例如$add.这是正常的,也对数组有效.有关方法的详细信息,以及如何使用它们的详细信息,请参阅FirebaseArray的文档.