试图从工厂的ref.on()返回值到控制器

时间:2016-03-13 21:39:46

标签: javascript angularjs firebase

我试图将工厂中Firebase查询的值检索到我的控制器但没有成功。任何人都有想法??

控制器:

main.controller("mainCtrl", function($scope, totalusers){
  $scope.city = "whatever";
  $scope.total = totalusers.getusers($scope.city);
});

工厂(我有查询来检索有多少用户指定了名称):

app.factory("totalusers", function(FURL) {
    var gettotalusers      = {};
    gettotalusers.getusers = function(city) {
        var tusers = new Firebase(FURL + "/Users/" + city);
        var count  = 0;

        tusers.on("value", function(snapshot) {
            snapshot.forEach(function(child) {
                if (child.val().Name != undefined) {
                    count++;
                }
            });
            var total = count;
            return total;
        });

    }
    return gettotalusers;
});

任何线索都会很棒,谢谢;)

2 个答案:

答案 0 :(得分:2)

以异步方式访问firebase值,以便在将total分配给$q时计数值仍为0,然后立即返回。您可以使用app.factory("totalusers", function(FURL, $q){ var gettotalusers = {}; gettotalusers.getusers = function(city){ var tusers = new Firebase(FURL + "/Users/" + city); var count = 0; var deferred = $q.defer(); tusers.on("value", function(snapshot){ snapshot.forEach(function(child) { if(child.val().Name != undefined){ count++; } }); deferred.resolve(count); }); return deferred.promise; } return gettotalusers; }); 服务创建承诺,并在firebase回调返回时解析它

main.controller("mainCtrl", function($scope, totalusers){
  $scope.city = "whatever";
  totalusers.getusers($scope.city).then(
    function(total) {
      $scope.total = total;
    },
    function(err) {
      // handle error
    }
  );
});

然后在您的控制器中,您无法直接分配结果。你需要在promise处理程序方法中这样做:

var total = snapshot
  .filter(function(item) { return child.val().Name !== undefined })
  .reduce(function(acc, curr) {
    return acc + curr;
  }
);

有关详细信息,请参阅$ q文档并阅读有关promises概念的内容。 https://docs.angularjs.org/api/ng/service/$q

您还可以尝试使用filter和reduce以更实用的方式编写计数:

{{1}}

答案 1 :(得分:2)

在这种情况下使用ref.on()是一个坏主意,因为即使在函数完成后它仍将继续同步该节点。您应该致电ref.off(),或者更简单地使用ref.once()。如果您使用的是最新版本的Firebase,则会返回一个承诺,这意味着您不需要$q

app.factory("totalusers", function(FURL) {
    var gettotalusers = {};

    gettotalusers.getusers = function(city) {
        var tusers = new Firebase(FURL + "/Users/" + city);

        return tusers.orderByChild("Name")
                     .startAt(false)
                     .once("value")
                     .then(function(snapshot) {
            return snapshot.numChildren();
        });
    };

    return gettotalusers;
});