Javascript 正在尝试将工厂中的ref.on()值返回给控制器
我正在尝试从工厂中的Firebase查询检索值到控制器,但没有成功。有人有主意吗 控制器:Javascript 正在尝试将工厂中的ref.on()值返回给控制器,javascript,angularjs,firebase,Javascript,Angularjs,Firebase,我正在尝试从工厂中的Firebase查询检索值到控制器,但没有成功。有人有主意吗 控制器: main.controller("mainCtrl", function($scope, totalusers){ $scope.city = "whatever"; $scope.total = totalusers.getusers($scope.city); }); 工厂(在这里我可以查询有多少用户指定了名称): 任何线索都很好,谢谢;) 对firebase值的访问是异步完成的,因此当将其
main.controller("mainCtrl", function($scope, totalusers){
$scope.city = "whatever";
$scope.total = totalusers.getusers($scope.city);
});
工厂(在这里我可以查询有多少用户指定了名称):
任何线索都很好,谢谢;) 对firebase值的访问是异步完成的,因此当将其分配给
总计时,计数值仍然为0,然后立即返回。您可以使用$q
服务创建承诺,并在firebase回调返回时解决它
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;
});
然后在控制器中,不能直接分配结果。您需要在承诺处理程序方法中这样做:
main.controller("mainCtrl", function($scope, totalusers){
$scope.city = "whatever";
totalusers.getusers($scope.city).then(
function(total) {
$scope.total = total;
},
function(err) {
// handle error
}
);
});
有关更多详细信息,请参阅$q文档并阅读有关承诺的概念。
您还可以尝试使用filter and reduce以更实用的方式编写计数:
var total = snapshot
.filter(function(item) { return child.val().Name !== undefined })
.reduce(function(acc, curr) {
return acc + curr;
}
);
访问firebase值是异步完成的,因此当将其分配给总计时,计数值仍然为0,然后立即返回。您可以使用$q
服务创建承诺,并在firebase回调返回时解决它
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;
});
然后在控制器中,不能直接分配结果。您需要在承诺处理程序方法中这样做:
main.controller("mainCtrl", function($scope, totalusers){
$scope.city = "whatever";
totalusers.getusers($scope.city).then(
function(total) {
$scope.total = total;
},
function(err) {
// handle error
}
);
});
有关更多详细信息,请参阅$q文档并阅读有关承诺的概念。
您还可以尝试使用filter and reduce以更实用的方式编写计数:
var total = snapshot
.filter(function(item) { return child.val().Name !== undefined })
.reduce(function(acc, curr) {
return acc + curr;
}
);
在这种情况下使用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;
});
在这种情况下使用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;
});
谢谢你的快速回复。它运行得非常好。我不知道过滤器和减压器,但我要看一下并检查一下。如果你有一个例子,这将是很酷的。无论如何,我对FialBaseAPI没有任何经验,所以请考虑“ANNID MunSURR”的解释,并使用FielaseAPI返回的承诺。如果您想了解更多关于数组函数的信息,我认为mozilla文档是一个很好的资源:感谢您的快速回复。它运行得非常好。我不知道过滤器和减压器,但我要看一下并检查一下。如果你有一个例子,这将是很酷的。无论如何,我对FialBaseAPI没有任何经验,所以请考虑“ANNID MunSURR”的解释,并使用FielaseAPI返回的承诺。如果你想了解更多关于数组函数的信息,我认为mozilla文档是一个很好的资源:您好@AnidMonsur,您说得对,我注意到ref.on()将继续关注,所以我改为ref.once()。虽然上面的代码并不完全是我想要做的,因为我需要的是检查有多少保存到firebase中的“名称”的用户可用,并对他们进行计数,但您所做的是对所有用户进行计数。无论如何,谢谢。啊,好的。更新了我对该场景的回答。从false开始
由于Firebase的订单非常感谢您的帮助,我尝试了您的代码,它运行得非常好,我只需要更新到最新的Firebase版本(2.4.1),因为我对.once()有一个错误,它只有一个参数,无论如何,现在它工作得很好,非常感谢。我只是注意到它仍然在计算所有用户,因为我尝试测试它的名称:“在firebase中的一个用户中,但它仍然计算所有用户,我刷新页面以重新加载代码,但它仍然是。”
是一个空字符串。您的原始代码也会考虑到这一点,因为它不是未定义的
。您好@AnidMonsur,您是对的,我注意到ref.on()将继续监视,所以我改为ref.once()。虽然上面的代码并不完全是我想要做的,因为我需要的是检查有多少保存到firebase中的“名称”的用户可用,并对他们进行计数,但您所做的是对所有用户进行计数。无论如何,谢谢。啊,好的。更新了我对该场景的回答。从false开始
由于Firebase的订单非常感谢您的帮助,我尝试了您的代码,它运行得非常好,我只需要更新到最新的Firebase版本(2.4.1),因为我对.once()有一个错误,它只有一个参数,无论如何,现在它工作得很好,非常感谢。我只是注意到它仍然在计算所有用户,因为我尝试测试它的名称:“在firebase中的一个用户中,但它仍然计算所有用户,我刷新页面以重新加载代码,但它仍然是。”
是一个空字符串。您的原始代码也会计算在内,因为它不是未定义的。