为什么仅使用 AngularFire 绑定到我的视图的第一个元素?

Why are binding to my view only the first element using AngularFire?

我无法在我的视图中显示 Firebase DB 上的内容存储。我知道 Firebase 是异步的。这是我的 Firebase 数据库中的当前结构:


代码:

    var bigObject = {};

    // Find all recognitions
    var ref = firebase.database().ref('recognitions');

    ref.once('value').then(function(snapshot) {
        bigObject = snapshot.val();
        // Loop through all recognitions
        for (o in bigObject) {
            var ref2 = firebase.database().ref('employees').child(bigObject[o].employee);
            ref2.once('value').then(function(snapshot2) {
                bigObject[o].profile = snapshot2.val();
                // Bind the content to the view
                $scope.$apply(function() {
                  $scope.data = bigObject;
                });
            });
        }
    });

我担心的是为什么绑定到我的范围只是 bigObject 的第一个元素?我想这是一个异步错误。怎么解决呢?

您 运行 进入 infamous loop issue

问题是当您的回调执行时,o 的值不再是您期望的值。

这是一个简化的示例,其中第一个版本演示了您的代码本质上发生了什么,第二个版本展示了解决问题的一种方法:

/**
 * This wont work properly
 */
var obj = {
  a: 'Original',
  b: 'Original',
  c: 'Original'
}

for (var i in obj) {
  var fn = function() {
    obj[i] = 'Updated'
  }
  setTimeout(fn, 4)
}

setTimeout(function() {
  console.log('Object 1', obj)
}, 20)


/**
 * ...but this will
 */
 
var obj2 = {
  a: 'Original',
  b: 'Original',
  c: 'Original'
}

for (var i in obj2) {
  var fn = function(i) {
    obj2[i] = 'Updated'
  }.bind(this, i);
  setTimeout(fn, 4)
}

setTimeout(function() {
  console.log('Object 2', obj2)
}, 60)

当然有很多方法可以解决这个问题,但一个简单的解决方案是将适当的索引绑定到您的回调。