我试图将工厂中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;
});
任何线索都会很棒,谢谢;)
答案 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;
});