我有一个使用 AngularJS 和 NodeJS 后端的简单网站。
它有多个页面,如主页、登录/注册页面等。
我想实现一个“聊天”页面,您可以在其中使用 socket.io 向其他客户端发送消息。我已经让那部分工作了,使用本地 Controller (本地,我的意思是在单个页面上激活 - 聊天页面)。
问题是,我希望聊天系统是全局的(即客户端可以在主页上接收消息,但它们仍然只会在返回聊天页面时显示)。
我在设置全局聊天 Controller (在所有页面上都处于事件状态)时遇到问题。
下面是我如何包含它:
<body ng-controller="AppCtrl"> <!-- include main controller -->
<div ng-include="'header.tpl.html'"></div>
<div ng-controller="ChatCtrl" class="page"> <!-- include global Chat controller -->
<div ng-view class="container"></div>
</div>
<div ng-include="'footer.tpl.html'"></div>
<!-- ...etc. -->
</body>
这工作得很好,但似乎我无法从我的聊天页面访问值。从 Chat Controller 声明的函数仍然可以调用,但“$scope.message”值(包含正在键入的消息)始终为空。
这是我的聊天 Controller (实际上称为 TravelCtrl)
angular.module('base').controller('TravelCtrl', //['$scope', 'security',
function($rootScope, $scope, security, NgMap, $geolocation, socket){
$scope.messages = [];
// Socket listeners
// ================
socket.on('init', function (data) {
$scope.name = data.name;
$scope.users = data.users;
});
socket.on('send:message', function (message) {
$scope.messages.push(message);
});
socket.on('change:name', function (data) {
changeName(data.oldName, data.newName);
});
socket.on('user:join', function (data) {
$scope.messages.push({
user: 'Server',
text: 'User ' + data.name + ' has joined.'
});
$scope.users.push(data.name);
});
// add a message to the conversation when a user disconnects or leaves the room
socket.on('user:left', function (data) {
$scope.messages.push({
user: 'chatroom',
text: 'User ' + data.name + ' has left.'
});
var i, user;
for (i = 0; i < $scope.users.length; i++) {
user = $scope.users[i];
if (user === data.name) {
$scope.users.splice(i, 1);
break;
}
}
});
// Private helpers
// ===============
var changeName = function (oldName, newName) {
// rename user in list of users
var i;
for (i = 0; i < $scope.users.length; i++) {
if ($scope.users[i] === oldName) {
$scope.users[i] = newName;
}
}
$scope.messages.push({
user: 'Server',
text: 'User ' + oldName + ' has been authenticated as ' + newName + '.'
});
}
// Methods published to the scope
// ==============================
$scope.changeName = function () {
socket.emit('change:name', {
name: $scope.newName
}, function (result) {
if (!result) {
alert('There was an error changing your name');
} else {
changeName($scope.name, $scope.newName);
$scope.name = $scope.newName;
$scope.newName = '';
}
});
};
$scope.sendMessage = function () {
socket.emit('send:message', {
message: $scope.message
});
// add the message to our model locally
$scope.messages.push({
user: $scope.name,
text: $scope.message
});
// clear message box
$scope.message = '';
};
// ================
var init = function () {
$scope.newName = security.currentUser.username;
$scope.changeName();
}
if ($rootScope.hasLoaded() && $scope.name != security.currentUser.username) {
init();
} else {
$rootScope.$on('info-loaded', init);
}
}
//]
);
以及聊天页面本身。奇怪的是,连接的用户和消息显示正确,但 Controller 似乎无法检索键入的消息。
<div class='col'>
<h3>Users</h3>
<div class='overflowable'>
<p ng-repeat='user in users'>{{user}}</p>
</div>
</div>
<div class='col'>
<h3>Messages</h3>
<div class='overflowable'>
<p ng-repeat='message in messages' ng-class='{alert: message.user == "chatroom"}'>{{message.user}}: {{message.text}}</p>
</div>
</div>
<div class='clr'>
<form ng-submit='sendMessage()'>
Message: {{message}}<br/>
<input size='60', ng-model='message'/>
<input type='submit', value='Send as {{name}}'/>
</form>
</div>
当按下“发送”按钮时,AngularJS 成功调用了 sendMessage 函数,但检索到的“消息”值是一个空字符串,导致它发送一个空的 socket.io 消息。
我是 AngularJS 的新手,所以我的方法可能完全荒谬。我确信我遗漏了一些明显的东西,但在再次阅读文档后,我似乎真的找不到什么。
这是组织 AngularJS 应用程序的正确方法吗?
预先感谢您的帮助。
最佳答案
最近构建了一个大型 Angular/Socket.IO 应用程序,我强烈建议您将所有 Socket 实现放入一个服务中。该服务将维护您所有的套接字状态,并允许您将其注入(inject)任何所需的 Controller 。这将允许您拥有聊天的主页,但仍然能够在应用程序的其他区域显示通知、聊天用户信息等。
关于javascript - 在 AngularJS 中使用范围和 Controller 时发生冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34425274/