我正在尝试创建一个小型聊天应用来帮助我学习AngularFire(Firebase + AngularJS)。我想要获得的唯一功能是能够创建聊天室,然后能够在每个房间聊天。顺便说一句,如果重要的话,我在Rails中这样做(我的用户登录,一切都通过Rails处理)。
到目前为止,我将此作为我的示例代码,这就是视图的样子:
<div ng-controller="RoomsCtrl">
<div ng-repeat="rm in rooms">
<div>
<ul>
<li class="message phm pvm pull-left" ng-repeat="msg in messages">
<span class="message-author">{{msg.from}}</span>
<span class="message-body">{{msg.body}}</span>
<span class="message-timestamp">{{msg.timestamp | date:'MMM d, yyyy h:mm a'}}</span>
</li>
</ul>
</div>
<form>
<span class="hidden"><%= current_user.full_name %></span>
<textarea ng-model="msgBody" ng-keydown="addMessage($event)" placeholder="What's on your mind..."></textarea>
</form>
</div>
<form>
<input type="text" ng-model="roomName" ng-keydown="addRoom($event)" placeholder="Enter a room name..."><
</form>
</div>
这是我的AngularFire脚本:
var app = angular.module("ChatApp", ["firebase"]);
function RoomsCtrl($scope, $firebase) {
var organizationId;
if (gon) {
organizationId = gon.organization_id;
}
var orgRef = new Firebase("https://glowing-fire-7051.firebaseio.com/"+organizationId);
$scope.rooms = $firebase(orgRef);
$scope.addRoom = function(e) {
if (e.keyCode != 13) return;
$scope.rooms.$add({name: $scope.roomName, timestamp: new Date().getTime()})
$scope.roomName = "";
e.preventDefault();
}
$scope.messages = $firebase(orgRef);
$scope.addMessage = function(e) {
if (e.keyCode != 13) return;
$scope.messages.$add({name: $scope.msgName, body: $scope.msgBody, timestamp: new Date().getTime()})
$scope.msgBody = "";
e.preventDefault();
}
}
每个用户belongs_to
和Organization
正如gon
部分所见,它只是获取current_user
所属组织的ID。我对addRoom
的代码确实在组织下创建了一个房间。 Forge数据如下所示:
<my forge id>
1
JHiiMka5OloVaqf-sA7
name: "Test Room"
timestamp: 1394500795299
JHjA0rwIDJNVDU4HVaF
name: "Another Room"
timestamp: 1394508307247
我也看到数据也反映在网站上。当我创建一个新房间时,房间会显示在该网站上。我的问题(我认为)仅在于messages
。我一直在研究几个小时,在嵌套引用的主题上几乎没有成功。我有点理解它,但我无法弄清楚我如何创建一个房间(动态通过网站),然后有权在Firebase中该房间的节点下创建消息。
我上面的视图代码向您展示了我认为它将如何显示在页面上。我的问题是,如何通过Firebase / AngularFire将两者结合在一起?在此先感谢您的帮助!如果您有任何问题可能会对任何事情有所了解,请告诉我。
更新
我通过他们的网站将此问题发送给Firebase支持,并收到回复,帮助我解决了几乎所有问题。我发送了一封跟进电子邮件,以澄清我不理解他们的回复并等到这里回来的部分。他们的建议是取代:
var orgRef = new Firebase("https://glowing-fire-7051.firebaseio.com/"+organizationId);
与
var orgRef = new Firebase("https://glowing-fire-7051.firebaseio.com/").child(organizationId);
这将为现有位置的子级创建新的Firebase参考。然后他们说这个用于$scope.messages
定义:
$scope.messages = $firebase(orgRef.child(roomID).child("messages"));
这假设在/ 1 / room /中有一个名为“messages”的孩子会保留你的信息。
我遇到问题的部分是消息定义中的.child(roomID)
,因为它告诉我它是未定义的(它是)。应该将它定义为......我假设它应该是新创建的房间的ID?
答案 0 :(得分:1)
我终于在Firebase + AngularJS谷歌小组上发布了我的问题的答案。我错过了几件事。这是我的最终代码:
var app = angular.module("ChatApp", ["firebase"]);
function RoomsCtrl($scope, $firebase) {
var organizationId;
if (gon) {
organizationId = gon.organization_id;
}
var orgRef = new Firebase("https://<my forge id>.firebaseio.com/").child(organizationId);
$scope.rooms = $firebase(orgRef.child('rooms'));
$scope.addRoom = function(e) {
if (e.keyCode != 13) return;
$scope.rooms.$add({name: $scope.roomName, timestamp: new Date().getTime()}).then(function(ref){
var roomId = ref.name();
$scope.messages = $firebase(orgRef.child('rooms').child(roomId).child("messages"));
});
$scope.roomName = "";
e.preventDefault();
}
$scope.addMessage = function(e) {
if (e.keyCode != 13) return;
$scope.messages.$add({name: $scope.msgName, body: $scope.msgBody, timestamp: new Date().getTime()})
$scope.msgBody = "";
e.preventDefault();
}
}
我缺少的主要部分是.then()
回调,我没有正确地将$scope.messages
的定义设置为引用父房间的位置。这些行是修复的主要部分:
$scope.rooms.$add({name: $scope.roomName, timestamp: new Date().getTime()}).then(function(ref){
var roomId = ref.name();
$scope.messages = $firebase(orgRef.child('rooms').child(roomId).child("messages"));
});
希望这可以帮助其他有类似问题的人。