【发布时间】:2015-09-29 00:19:09
【问题描述】:
我要处理聊天私信,所以我有2个服务:
- ChatSocket 连接到服务器并返回一个套接字
- ChatHistory 将每个私人聊天会话的聊天消息保存在地图中
在我的 ChatSocket 服务中,我侦听聊天私人消息并将它们添加到聊天历史记录中:
.factory('ChatSocket', function (ChatHistory) {
var socket = io.connect(/* ... */);
socket.on('priv_msg', function (data) {
ChatHistory.push(data.user, data.msg);
});
});
我也使用 Angular ui 路由器,因此我可以通过这种方式拥有多个聊天“窗口”:
.config(function ($stateProvider) {
$stateProvider.state('app.chat', {
url: '/chat/:uid',
views: {
'content': {
templateUrl: 'templates/chat.html',
controller: function ($scope, $stateParams, ChatHistory) {
$scope.messages = ChatHistory.get($stateParams.uid);
/*
This returns an array that looks like:
[
{ nickname: 'myself', msg: 'hello' },
{ nickname: 'someone', msg: 'hi' },
{ nickname: 'myself', msg: 'how r u?' },
]
*/
}
}
}
}
});
这很好用,除了因为 $scope.messages 在外部服务中更新,我真的不确定在哪里调用 $apply。
当然,我可以在控制器本身的“priv_msg”事件上添加一个监听器并在那里调用 $apply,但这看起来有点矫枉过正:
ChatSocket.on('priv_msg', function (data) {
if (data.user.id == $stateParams.id) {
$scope.$apply();
}
});
知道如何更新消息吗?我的解决方案可能是正确的,但我对 angular 有点陌生,所以可能有更好的方法来实现这一点,所以我完全愿意接受任何建议/示例。
【问题讨论】:
-
您的服务中没有特定的控制器,因此没有范围。你需要的是events。
-
所以你的意思是在我的服务中发出一个事件并在每个聊天控制器中收听它?这就像在每个控制器中监听“priv_msg”套接字事件一样,不是吗?
-
不完全是。您广播特定于收到消息的用户的事件。然后你的 ChatController 知道,哪个用户拥有它并且只监听这个用户的事件。如果您想与多个其他用户有多个聊天窗口,甚至是用户-用户组合。
-
当你说具体时,你是指它的名字吗?比如:
$rootScope.$emit('priv_msg_' + user.id)然后$scope.$on('priv_msg_' + $stateParams.id, function () { $scope.$apply(); }); -
是的,类似的。甚至 $rootScope.$emit('priv_msg_' + user.id + '/' + data.msg.from_user.id);
标签: angularjs angular-ui-router