使用$ loaded with $ firebaseObject更新值VS firebase SDK更新。利弊

时间:2015-06-17 00:18:47

标签: angularjs firebase angularfire

假设我有与Firebase操作的服务协议:

angular.module('myApp').factory('taskOfferService', ['FURL', '$firebaseArray', '$firebaseObject', '$q', 'taskService', taskOfferService]);

function taskOfferService(FURL, $firebaseArray, $firebaseObject, $q, taskService) {

    var ref = new Firebase(FURL);

    var Offer = {
        acceptOffer: function(taskId, offerId, runnerId) {
            var offerRef = ref.child('taskOffers').child(taskId).child(offerId);
            var taskUpdate = $q.defer();
            offerRef.update({accepted: true}, function(error) {
                if (error) {
                    console.log('Update offer accepted value failed!');
                } else {
                    var taskRef = ref.child('tasks').child(taskId);

                    taskRef.update({status: "assigned", runner: runnerId}, function(error) {
                        if (error) {
                            console.log('Update task status failed!');
                            taskUpdate.reject(false);
                        } else {
                            taskUpdate.resolve(true);
                        }
                    });

                }
            });
            return taskUpdate.promise;
        },  
    };
    return Offer;
}
    })();

我有一个控制器需要调用此服务,需要在更新成功时等待承诺 - 调用toaster.pop:

$scope.acceptOffer = function(offerId, runnerId) {
       taskOfferService.acceptOffer($scope.selectedTask.$id, offerId, runnerId).then(function(){
         toaster.pop('success', 'Offer is accepted.');
       }); 
    };

此代码有效,它遵循Firebase文档的建议。但正如您在我的服务中所看到的,为了获得承诺,我需要在更新回调中使用更新回调...我的观点是,Firebase SDK在完成后不会返回承诺,我需要创建此承诺这是很多代码...

如果我使用firebaseObject(angularFire 1.0),它将遇到此处列出的问题:saving new property overwrites firebase object

根据@sinan使用ANTIPATTERN,代码可以更清晰:

acceptOffer: function(taskId, offerId, runnerId) {
            var o = $firebaseObject(ref.child('taskOffers').child(taskId).child(offerId));
            o.$loaded().then(function(){
                o.accepted = true;
                o.$save().then(function(){
                    var oTask = $firebaseObject(ref.child('tasks').child(taskId));
                    oTask.$loaded().then(function(){
                        oTask.status = "assigned";
                        oTask.runner = runnerId;
                        oTask.$save();
                    });
                })       
        },

关键是,使用“ANTIPATTERN”,我可以使用$ save() - 它返回一个promise,因此我的firebase服务中不需要$ q服务。在我看来,它看起来更加清晰。两种方法都有效。

但是,根据文件:

  

“$ loaded()方法应该小心使用,因为它只在初始加载后调用一次。除了调试之外用它做任何事情都是不好的做法。”

我发现自己使用$ loaded A LOT!请建议最好的方法来解决这个问题。

1 个答案:

答案 0 :(得分:2)

Firebase有一个JavaScript SDK,可以将平台的功能公开给JavaScript环境。 AngularFire是该SDK之上的一个库,可以更轻松地将Firebase数据绑定到AngularJS Web界面。

这里的示例是一个简单的数据操作操作。您没有将数据绑定到屏幕上,因此您不需要AngularFire。我也认为没有必要使用承诺。

据我所知,这与你上一个脚本完全相同:

acceptOffer: function(taskId, offerId, runnerId) {
  var offer = ref.child('taskOffers').child(taskId).child(offerId);
  offer.update({ accepted: true }, function() {
    var task = ref.child('tasks').child(taskId);
    task.update({ status: "unassigned", runner: runnerId });
  });
}

这不仅会缩短,还会阻止下载数据,然后再更新数据。

最好的部分?由于AngularFire是在常规Firebase JavaScript SDK之上构建的,因此它们可以完美地互操作。因此,如果在另一个地方您通过观察到$firebaseObject的AngularJS视图实际显示任务或提供,它将立即显示更新的值。

更新

如果您需要在保存acceptOffer方法时执行某些操作,则可以传入回调:

acceptOffer: function(taskId, offerId, runnerId, callback) {
  var offer = ref.child('taskOffers').child(taskId).child(offerId);
  offer.update({ accepted: true }, function(error) {
    if (!error) {
      var task = ref.child('tasks').child(taskId);
      task.update({ status: "unassigned", runner: runnerId }, callback);
    }
    else {
      callback(error)
    }
  });
}

然后你调用它:

taskOfferService.acceptOffer($scope.selectedTask.$id, offerId, runnerId, function(error) {
  if (!error) {
    toaster.pop('success', 'Offer is accepted.');
  }
  else {
    console.error('Something went wrong: '+error);
  }
}); 

你绝对可以宣传acceptOffer方法。但这不是必要的。