以下是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
一次的原因。该名称有点违反直觉,我可能会称其为registerMessageHandler
或registerForNewMessages
之类的东西。无论哪种方式:都会为每个添加的子项触发回调,直到您将其关闭(通过调用
ref.off("child_added"
)或直到页面重新加载为止。这称为异步操作:无论原始流在何处,都会发生回调。回调的流程和您的主要代码是异步的。从某种意义上讲,它类似于常规的JavaScript setInterval
(在您的主代码继续运行时,它仍保持异步触发)或常见的XMLHttpRequest(通常在其调用方法返回后将触发)。