以下是official firebase documentation中的示例代码

var app = angular.module("myChatRoom", []);
app.factory("ChatService", function() {
  var ref = new Firebase("https://<your-firebase>.firebaseio.com/chat");
  return {
    getMessages: function() {
      var messages = [];
      ref.on("child_added", function(snapshot) {
        messages.push(snapshot.val());
      });
      return messages;
    },
    addMessage: function(message) {
      ref.push(message);
    }
  }
});
app.controller("ChatCtrl", ["$scope", "ChatService",
  function($scope, service) {
    $scope.user = "Guest " + Math.round(Math.random()*101);
    $scope.messages = service.getMessages();
    $scope.addMessage = function() {
      service.addMessage({from: $scope.user, content: $scope.message});
      $scope.message = "";
    };
  }
]);


我想了解这里发生了什么,因为我不确定为什么会真正起作用。

控制器触发时,getMessages()仅被调用一次。尽管如此,即使以后从未调用getMessages()也会触发事件绑定。同样,$ scope属性也会更新。

这是为什么?另外,这是将Firebase与Angular服务/工厂一起使用的推荐方法吗?

最佳答案

getMessages中,您具有以下呼叫:

ref.on("child_added", function(snapshot) {
  ...


这注册了一个回调,每当一个孩子被添加到您的Firebase聊天中时,该回调便被调用。

即使getMessages退出,该回调也将保持注册状态。这就是为什么您只需要调用getMessages一次的原因。该名称有点违反直觉,我可能会称其为registerMessageHandlerregisterForNewMessages之类的东西。

无论哪种方式:都会为每个添加的子项触发回调,直到您将其关闭(通过调用ref.off("child_added")或直到页面重新加载为止。这称为异步操作:无论原始流在何处,都会发生回调。回调的流程和您的主要代码是异步的。从某种意义上讲,它类似于常规的JavaScript setInterval(在您的主代码继续运行时,它仍保持异步触发)或常见的XMLHttpRequest(通常在其调用方法返回后将触发)。

09-16 23:32