在foreach函数Angular js Firebase之外访问$ scope

时间:2017-06-27 09:13:55

标签: javascript angularjs firebase firebase-realtime-database nested

这是代码:我循环遍历数据以获得我需要的值,而且我得到了它。 问题是我如何在控制器内的其他功能中访问此循环之外的值。已将正确的值分配给$ 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);
       }
   });
});

};

4 个答案:

答案 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;
});