使用Firebase + AngularJS进行聊天应用时,嵌套节点出现问题

时间:2014-03-11 03:55:13

标签: javascript ruby-on-rails angularjs angularfire

我正在尝试创建一个小型聊天应用来帮助我学习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_toOrganization正如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?

1 个答案:

答案 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"));
});

希望这可以帮助其他有类似问题的人。