如何在Angular工厂中使用Firebase查询?

时间:2014-11-26 20:44:52

标签: angularjs firebase

我试图让新的Firebase查询在我的工厂中运行,但我遇到了困难。我想要返回' logo'的价值。根据对手的名字,从我的对手桌子出来。我可以通过运行Firebase文档的console.log获取示例:

function OpponentService($firebase) {
    var factory = {};
    var _url = 'https://somefirebaseproject.firebaseio.com/opponents';
    var _ref = new Firebase(_url);

    factory.getLogo = function(opponent) {
        _ref.orderByChild('name').equalTo(opponent).on("child_added", function(snapshot){
            console.log(snapshot.val().logo);
        });
    };

    return factory;
}

当我在控制器中使用OpponentService.getLogo(opponentName)呼叫我的工厂时,我在控制台中获得了正确的徽标ID。但是如何返回值而不是将其发送到我的控制台?我想将它存储在这样的变量中:$scope.opponentLogo = OpponentService.getLogo(opponentName)。我尝试了几种变体,返回语句如下:

factory.getLogo = function(opponent) {
        _ref.orderByChild('name').equalTo(opponent).on("child_added", function(snapshot){
            return snapshot.val().logo;
        });
};

但显然我并不完全理解工厂如何在Angular中工作,因为我得到了undefined。可能是价值还没有可用,我应该在某种程度上使用承诺?谁可以指出我正确的方向?

1 个答案:

答案 0 :(得分:5)

您从Firebase on()调用中的匿名函数返回徽标的值,但您没有从getLogo()返回任何内容。

回复承诺将是一个很好的方法。这是您使用AngularFire检索对手徽标的方式,如果没有保证opponentName将是唯一的:

// getLogo() returns a promise that you can bind to the UI.
// When loading finishes, the binding will get the opponent's logo value.
factory.getLogo = function (opponentName) {
    var opponentsArray = $firebase(_ref.orderByChild('name').equalTo(opponentName)).$asArray();

    // $loaded() returns a promise, so we can use the then() method to add
    // functionality when the array finishes loading and the promise resolves.
    var r = opponentsArray.$loaded().then(function () {
        // Now return the logo for the first matching opponent
        return opponentsArray[0].logo;
    });

    return r;
};

如果opponentName 唯一,我会重新考虑数据结构,以便您可以使用opponentName作为对手的关键字。然后你将保证得到一个单一的对手并可以用:

获取它
var opponent = $firebase(_ref.child(opponentName)).$asObject();

如果您没有使用AngularFire,则可以使用Angular的$q服务返回承诺。以下应该有效:

factory.getLogo = function(opponent) {
    $q(function (resolve, reject) {
        function successCallback(snapshot) {
            resolve(snapshot.val().logo);
        };

        function cancelCallback(error) {
            reject(error);  // pass along the error object
        };

        _ref.orderByChild('name').equalTo(opponent)
            .on("child_added", successCallback, cancelCallback);
    });
};

您可以将getLogo()的结果分配给范围变量,当Firebase返回值时,绑定会在UI中更新。