【问题标题】:AngularFire V1.2 $firebaseArray() $loaded() only called once [duplicate]AngularFire V1.2 $firebaseArray() $loaded() 只调用一次[重复]
【发布时间】:2018-06-07 10:06:03
【问题描述】:

我在数组上使用 AngularFire 和 promises ($loaded() on firebaseArray())。

目前,我正在使用以下代码:

问题:我转到第 1 页,数据已加载,一切正常。转到第 2 页并返回第 1 页。现在$loaded() 在我进行整页刷新之前不起作用。我该如何解决这个问题?

app.factory('Items', ['FBURL', '$firebaseArray', function(FBURL, $firebaseArray) {
    return {
      ofCategory: function(catId){
        var ref = new Firebase(FBURL);
        var refSearch = new Firebase.util.NormalizedCollection(...).select(...).ref(); 
        var allItems= refSearch.orderByChild(...);
        return $firebaseArray(allItems);
      }
    }; 
}]);

第1页:

function readData() { 
  if($scope.Items) { 
     $scope.Items.$destroy();
     $scope.Items= null;
  }   
  $scope.Items = Items.ofCategory($routeParams.id);
  $scope.Items.$loaded().then(function(itm) {
        ...
  });
}

第2页:

$scope.Items= Items.ofCategory($routeParams.id);

Firebase 文档1 说:“$loaded() 返回一个承诺,该承诺在从我们的数据库下载初始记录后解决。这只调用一次并且应该小心使用”,这可能就是我在这里得到的。

我的尝试:如图所示,在第 1 页上的 readData() 函数中,我在任何新加载之前销毁了 $scope.Items 变量。但它似乎没有做任何事情。 AFAIU,$loaded() 正在处理firebaseArray(),因此销毁$scope 数组可能无济于事。那么,在不需要完全刷新页面的情况下,我还应该做些什么来完成这项工作?

【问题讨论】:

  • 你说“$loaded() 不起作用”是什么意思?有错误信息吗? .catch 是否返回错误?描述错误的行为。
  • @georgeawg,谢谢。没有错误。 .catch 没有发现任何错误。只是代码在加载一次后没有进入$loaded(),这可能是它应该做的。有人可能还会问“为什么不坚持使用加载的数组,为什么需要第二次调用?”我的回应是,因为我不只是简单地使用加载的数组。我对这些项目做了一些事情,所以我需要在进行计算之前调用“$loaded()”来准备好数据。
  • 这怎么可能?此 GitHub 提交适用于 2014 年 1 月。我正在使用 2016 年 3 月发布的 AngularFire v1.2.0!之后的版本将不适用于 Firebase 2.x(我的当前版本)
  • 看起来第二次,它实际上并没有触发loaded(),所以then()部分没有被调用..

标签: angularjs firebase firebase-realtime-database angularfire angular-promise


【解决方案1】:

我听说应该避免使用 AngularFire,这似乎是一个很好的理由。

直接使用 firebase API:

app.factory('FbItems', ['FBURL', '$q', function(FBURL, $q) {
    return {
      ofCategory: function(catId){
        var ref = new Firebase(FBURL);
        var refSearch = new Firebase.util.NormalizedCollection(...).select(...).ref(); 
        var allItems= refSearch.orderByChild(...);
        var promise = allItems.once('value').then(function(snapshot) {
            return snapshot.val();
        });
        return $q.when(promise);
      }
    }; 
}]);

使用$q.when 将 ES6 承诺转换为 AngularJS $q 承诺很重要。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。

用法:

function readData() { 
  promise = FbItems.ofCategory($routeParams.id);
  promise.then(function(items) {
      $scope.Items = items;
  }).catch(function(error) {
      console.log(error);
  });
}

【讨论】:

  • 感谢@georgeawg。这行var promise = allItems.once().then(function(snapshot) { 给了我一个TypeError: Cannot read property 'call' of undefined 错误。您能否详细说明为什么我们有 2 个退货?如果我们已经返回,我们什么时候可以到达return $q.when(promise);
  • 更新了答案。应该是.once('value')
  • 谢谢。我会稍等一下,看看 Firebase 的人是否可以评论我的原始代码?如果不是,我将把它作为 AngularFire 的一个问题提出(尽管他们提到使用 $loaded() 通常是一种不好的做法)
  • 我今天尝试了这个解决方案,但它不起作用,出现错误 (allItems.once(...).then is not a function)。可能是因为我使用的是NormalizedCollection
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
相关资源
最近更新 更多