AngularFire - $firebaseArray 可以 $add 但不能读取

AngularFire - $firebaseArray can $add but not read

我觉得我一定遗漏了一些非常基本的东西。这是我服务的一部分:

angular.module('fire')
  .constant('FIREBASE_URI', 'https://___.firebaseio.com/')

  .factory('syncArraySvc', function(FIREBASE_URI, $firebaseArray) {

    var buildingsUri = FIREBASE_URI + "buildings";
    var buildings = $firebaseArray(new Firebase(buildingsUri));
    console.log(buildings);

    var getBuildings = function() {
      return buildings;
    };
    var addBuilding = function(item) {
      buildings.$add(item);
    };
    return {
      getBuildings: getBuildings,
      addBuilding: addBuilding
    };
  });

中间的console.log只是returns一个空数组。如果我尝试从另一个控制器调用 syncArraySvc.getBuildings() 函数,我也会得到一个空数组。 $add(item)syncArraySvc.addBuilding(item) 一样有效。我错过了什么?

尝试在 getBuildings 函数内或调用它时使用 $timeout 服务。返回数据可能需要一些时间。

如果您查看 $add $firebaseArray,它会创建新项目并将其添加到 $firebaseArray 中,就像我们有 buildings 一样。但是,一旦您将项目添加到“$firebaseArray”,它就不会立即添加。它在 $add 承诺得到解决时被添加。

我认为你做的是正确的,只是你需要在 $add 承诺成功时调用 syncArraySvc.addBuilding(item) 方法。

要实现此方法,您需要 return 来自服务方法的承诺,如

var addBuilding = function(item) {
  return buildings.$add(item);
};

然后调用者函数将接受该承诺并在解决它时,他将调用 syncArraySvc.addBuilding(item) 方法以确保项目已添加到 buildings 数组中。

syncArraySvc.addBuilding({foo: "bar"}).then(function(addedItem){
    console.log(addedItem);
    console.log(syncArraySvc.addBuilding(item)); //this will show you updated list
})

其他答案帮助我指明了正确的方向。

API documentation 有一个代码示例似乎不需要将数据包装在承诺中:

var list = $firebaseArray(new Firebase(URL));
$scope.list = list;

但是,它确实指出您可以使用 $loaded 承诺在加载数据时收到通知。这就是我如何让它在我的项目中工作:

syncArraySvc.getBuildings().$loaded(function(data) {
  $scope.buildings = data;
});

我尝试在一个新项目中复制它,并且它在没有 $loaded 包装器的情况下始终有效,就像它们在第一个示例中显示的那样。对我来说,需要 $loaded 包装器是有意义的。如果没有它,我不明白它在第一个示例中如何工作。