延迟返回变量,直到数据从Firebase同步

时间:2014-10-29 11:14:50

标签: javascript angularjs loading firebase angularfire

我在app中使用angularfire使用angular和firebase。我有一些存储在firebase中的文本文档。我想获取所有这些文档并返回这些文档中所有段落的数组,以便使用angular进行操作。

我创建了一个服务,它将来自firebase的数据与可变文档同步。此服务具有以下功能,可将其更改为段落数组。

getParas: function(){
    var paras = [];
    for(var i=0;i< documents.length;i++){
        paras = paras.concat(documents[i].text.split('\n'));
    }
    return paras;
}

但是,由于数据从firebase同步的时间,函数在对寄生变量进行更改之前返回。

我已尝试使用documents.$loaded().then(function(){...,但不确定如何从getParas()函数返回此结果。

我见过article,但过滤器似乎不是最佳选择吗?

由于

马修

2 个答案:

答案 0 :(得分:2)

您有两种选择。

  1. 在加载页面之前解析“documents”变量 路由。
  2. 使用promises,并确保“getParas” 在将数据设置为“文档”变量后调用。
  3. 以下是一个解决方案,承诺在控制器中完成所有操作,您可以从此开始,然后尝试将其合并到您的服务中。

    .controller("YourCtrl", ["$scope", "$q", function($scope, $q){
      var promise = getFB();
      promise.then(function(){
        afterPromise();
      })
    
      function getFB(){
        var documentRef = new Firebase("YOURFIREBASERURL/documents")
        var fireDataDef = $q.defer()
    
        documentRef.once("value", function(snapshot){
          $scope.documents = snapshot.val();
          fireDataDef.resolve();
        })
        return fireDataDef.promise;
      }
    function afterPromise(){
        var $scope.paras = [];
        for(var i=0;i< $scope.documents.length;i++){
            $scope.paras = $scope.paras.concat(documents[i].text.split('\n'));
        }
      }
    }]
    

答案 1 :(得分:1)

由于这不是问题,我将忽略这样一个事实:你应该只是将段落存储在一个单独的路径中,这样你就可以把它们准备好去,而不是经历这个无关紧要的步骤每次阅读时解析它们。但我要指出的是,将数据存储起来是如何将其读回来的,这是朝着正确方向迈出的重要一步。

由于多种原因,在这里使用$ loaded是不正确的。首先,您已经获取了动态的实时数据,并将其转换为静态资产,在源数据发生变化时不会更新。如果是这种情况,也可以将其存储在Web服务器上的文件中并使用HTTP获取它。其次,利用$ loaded()通常意味着你正在为自己创造额外的工作并尝试微观管理AngularFire已经做得很好的事情,比如管理异步下载和操纵同步数组中的数据。

最有可能的是,您只想使用$extendFactory在数组原型上创建其他方法。

// create a factory that has a getParas method
app.factory('ListFactory', function($FirebaseArray) {
    return $FirebaseArray.$extendFactory({
        getParas: function() {
            var paras = [];
            for(var i=0; i < this.$list.length; i++){
                paras = paras.concat(this.$list[i].text.split('\n'));
            }
            return paras;
        }
    });
});

// create the synchronized list
app.factory('List', function(ListFactory, $firebase) {
    return function(ref) {
        return $firebase(ref, {arrayFactory: ListFactory}).$asArray();
    }
});

app.controller('ctrl', function(List, $window, $scope) {
     var ref = new $window.Firebase(URL);
     $scope.list = List(ref);
});

然后在您看来,只需引用新方法:

<pre>
{{list.getParas()|json}}
</pre>