这是代码:我循环遍历数据以获得我需要的值,而且我得到了它。 问题是我如何在控制器内的其他功能中访问此循环之外的值。已将正确的值分配给$ scope.theModel。
var refModels = firebase.database().ref("/users/" + $scope.UserID);
refModels.once('value').then(function (snapshot) {
snapshot.forEach(function (snapshot) {
var usersValue = snapshot.val();
console.log("users values", usersValue.carModel);
$scope.theModel = usersValue.carModel;
console.log("The model" + $scope.theModel); //output "e90"
});
$scope.processData();
});
所以我需要在函数之外使用值$ scope.theModel。我想要实现的目标是,我将使用$ scope.theModel - “e90”的值并将其与另一个DB ref进行比较,如果匹配则返回数据。请参阅另一个DB ref的代码:
$scope.processData = function (){
console.log("Process Model" + $scope.theModel); // returns undefined
$scope.carDetails = [];
firebase.database().ref("models").once('value').then(function(snapshot) {
snapshot.forEach(function(userSnapshot) {
var models = userSnapshot.val();
console.log(models);
if (models.brand == $scope.theModel){
$scope.carDetails.push(models);
}
});
});
};
答案 0 :(得分:2)
这是因为,refModels.once('value').then
是异步的,意味着JS开始执行并继续下一行console.log
并且console.log
执行时$scope.theModel
hasn'已经填充了数据。
我建议你读这个 Asynchronous vs synchronous execution, what does it really mean?
您仍然可以在其他功能中访问$scope.theModel
,但您必须先确保它已加载。
修改强>
refModels.once('value').then(function (snapshot) {
snapshot.forEach(function (snapshot) {
var usersValue = snapshot.val();
console.log("users values", usersValue.carModel);
$scope.theModel = usersValue.carModel;
console.log("The model" + $scope.theModel); //output "e90"
});
$scope.processData();
});
$scope.processData = function() {
// here $scope.theModel exists
// do some code execution here with $scope.theModel
// call your other firebase.database.ref("models") here
};
答案 1 :(得分:1)
好的,所以终于搞定了,使用Bunyamin Coskuner解决方案,我唯一需要解决的是返回$ scope.processData;
var UserID = firebase.auth().currentUser.uid;
var refModels = firebase.database().ref("/users/" + UserID);
refModels.once('value').then(function(snapshot) {
console.log(snapshot)
snapshot.forEach(function(childSnapshot) {
console.log(childSnapshot)
var usersValue = childSnapshot.val();
// var theModel = usersValue.carModel;
console.log("The model", usersValue.carModel); //output "e90"
$scope.theModel = usersValue.carModel;
***return $scope.processData;*** // we have to return it here
});
$scope.processData();
});
$scope.processData = function (){
console.log("Process Model" + $scope.theModel); // now returns the value e90
$scope.carDetails = [];
firebase.database().ref("models").once('value').then(function(snapshot) {
snapshot.forEach(function(userSnapshot) {
var models = userSnapshot.val();
console.log(models);
if (models.brand == $scope.theModel){
$scope.carDetails.push(models);
}
});
});
}
这似乎是新javascript开发人员犯的一个非常常见的错误,Async行为,因此很好地阅读它。
在这个解决方案中,我们从then函数内部调用了一个函数。这样,我们肯定会有可以在其他功能中使用的数据
答案 2 :(得分:0)
你的$scope.theModel
被设置在"然后"按预期阻塞,但是异步,这在第二个console.log(在函数外部)被调用后发生。
如果使用角度组件,则可以在$ onInit方法中初始化模型:
angular.module('app', []).component('myComponent', {
bindings: {
title: '@'
},
controller: function() {
this.$onInit = function() {
// Init the variable here
$scope.theModel = null;
});
//Following code should not be in the controller, but in a service (here just as sample)
var refModels = firebase.database().ref("/users/" + $scope.UserID);
refModels.once('value').then(function (snapshot) {
snapshot.forEach(function (snapshot) {
var usersValue = snapshot.val();
console.log("users values", usersValue.carModel);
// From this moment your variable is set and available outside
$scope.theModel = usersValue.carModel;
});
},
templateUrl: 'template.html'
});
答案 3 :(得分:0)
您可以观看价值变化。异步行为在另一个答案中解释。
$scope.$watch('theModel', function(newVal){
console.log(newVal);
});
另外我会在$ scope.theModel = usersValue.carModel上使用$ evalAsync();
$scope.$evalAsync(function(){
$scope.theModel = usersValue.carModel;
});