【问题标题】:angularfire, callback on retrieved dataangularfire,检索数据的回调
【发布时间】:2014-01-02 15:56:06
【问题描述】:

我想在我取回我的 firebase 数据后调用一个函数,但是,我没有在 ref 对象上看到任何类似 then 的 promise 函数。有什么建议吗?这是我的代码:

angular.module('myMod', ['firebase']).controller('myCtrl', ['$scope', '$firebase',
    function($scope, $firebase) {
        var ref = new Firebase('myfirebaseurl');

        $scope.data = $firebase(ref);

        // i want to do something like
        data.then(function(){
           someFunc();
        });

        // or something like
        $scope.$watch('data', function(){
            if($scope.data.desiredProperty) {
              doSomething();
            }
        });
    }]);

【问题讨论】:

  • 我可以在某个时间点之后使用 setTimeout 来运行我的函数,但是我认为这不是一个好的解决方案,因为数据可能会在不同的时间点下降。

标签: javascript angularjs firebase angularfire


【解决方案1】:

我浪费了大量时间尝试使用 Angularfire 完成所有工作,而实际上大多数 Firebase 功能在没有它的情况下更容易实现。

要满足您的要求,我建议如下:

var ref = new Firebase('myfirebaseurl');  // get your ref

// Called once with the initial data and again every time the data changes
ref.on("value", function(data) {
  $scope.data = data.val();
  someFunc();
});

上面的代码满足你的需要。检索数据时将调用一次,并在数据更新时再次调用。如果您只想在第一次加载数据时调用它,您可以使用:

ref.once("value", function(data) { ... }); 

【讨论】:

    【解决方案2】:

    AngularFire 为“加载”和“更改”事件提供事件处理程序。来自annotated source

    object.$on = function(type, callback) {
      switch (type) {
      case "change":
        self._onChange.push(callback);
        break;
      case "loaded":
        self._onLoaded.push(callback);
        break;
      default:
        throw new Error("Invalid event type " + type + " specified");
      }
    };
    

    所以你应该可以做这样的事情:

    var ref = new Firebase('myfirebaseurl');
    
    $scope.data = $firebase(ref);
    
    $scope.data.$on('loaded', function(){
        if($scope.data.desiredProperty) {
          doSomething();
        }
    });
    

    编辑:

    看起来当 AngularFire loaded 事件触发时,$scope.data 对象尚未完全填充。这似乎是一个已知问题,但有一些方法可以解决它。

    将数据作为参数访问您的loaded 回调函数:

    $scope.data.$on("loaded", function(data) {
      console.log(data);
    }
    

    完全跳过 AngularFire,直接使用 Firebase API:

    ref.on("value", function(data) {
      console.log(data.val());
    }
    

    【讨论】:

    • 这个解决方案对我不起作用,在 ref 对象上无法识别 $on 函数。
    • 有趣,我想知道这是版本问题还是您的 Firebase 数据中的某些内容不符合您的期望。我在this Plunk 中有一个工作示例,以防万一。您可以尝试慢慢更换位,直到它中断以查明问题。
    • on 函数似乎触发了,但是如果我测试数据的属性,比如说 x(反映在 db 结构中)它总是返回 undef。
    • 啊,我明白你在说什么。看起来$firebase 服务有一个$getIndex() 方法,它返回一个包含所有属性的数组。我已经用一些如何使用该方法测试属性的示例更新了我的 plunk。
    • 我遇到了和 OP 一样的问题。此处和新 AngularFire 文档中描述的 $on "已加载" 承诺无法正常工作。我正在尝试记录一个对象,即使它在 $on 中运行,它也总是返回 Undefined。如果我使用 SetTimout 并在 3 秒后调用它,我会得到该值。
    【解决方案3】:

    您需要结合使用 $loaded 和 $watch 承诺来处理从 Firebase 返回的数据。如需更多信息,请查看AngularFire Documentation

    如果您的数据是对象,请尝试以下代码。观察集合的变化有点不同,但基本相同。

    angular.module('myMod', ['firebase'])
      .controller('myCtrl', ['$scope', '$firebase', function ($scope, $firebase) {
    
        var data = $firebase(new Firebase(URL));
    
        //to take an action after the data loads, use the $loaded() promise
    
        data.$loaded.then(function () {
            console.log("loaded record:", data.$id, data.otherData);
            someFunc();
    
        //Register an event listener which will be notified any time there is a change to the data.
    
            data.$watch(function (event) {
                console.log(event);
                if (data.desiredProperty) {
                    doSomething();
                }
            });
        });
    
        //For three-way data bindings, bind it to the scope instead
    
        data.$bindTo($scope, "data");
    }]);
    

    我通常最终使用一些 AngularFire 绑定并将其与核心 Firebase SDK 提供的方法混合使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多