Javascript Socket.IO&;角度-$scope对象在套接字中未定义

Javascript Socket.IO&;角度-$scope对象在套接字中未定义,javascript,angularjs,socket.io,mean-stack,Javascript,Angularjs,Socket.io,Mean Stack,我正在使用Angular/Socket.IO编写一个简单的聊天程序。我尝试过几种方法,每次遇到这个问题时:在某个点上,当尝试使用套接字发送数据时,angular的$scope中控制器内设置的数据将变得未定义。例如: $scope.sendMessage = function() { console.log('sendMessage:'); console.log($scope.user); console.log($scope.joined[$scope.current]

我正在使用Angular/Socket.IO编写一个简单的聊天程序。我尝试过几种方法,每次遇到这个问题时:在某个点上,当尝试使用套接字发送数据时,angular的$scope中控制器内设置的数据将变得未定义。例如:

$scope.sendMessage = function() {
    console.log('sendMessage:');
    console.log($scope.user);
    console.log($scope.joined[$scope.current]);
    socket.emit('new_message', {message: $scope.newMessage, user: $scope.user, room: $scope.joined[$scope.current].name});
    $scope.newMessage = '';
};
在这里,$scope.user和$scope.joined[$scope.current]的console.logs都会打印我期望的值,但是在socket.emit函数中,$scope.user和$scope.joined[$scope.current]在登录服务器时会变得未定义

有人能说出这是为什么吗

以下是服务器代码:

// Set up dependencies

var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');

// Set up DB

require('./config/mongoose');

// Set up app

var app = express();

app.use(express.static(path.join(__dirname, './client')));
app.use(bodyParser.json());

var server = app.listen(54573, function(){
    console.log('NodeJS/Express/Socket.IO :54573');
})

// Set up routes

var routes = require('./config/routes')(app);

// Set up Socket.IO

var sockets = require('./config/sockets')(server);
以及socket.js文件:

module.exports = function(server) {

    var rooms = {};

    // Require Sockets, Set Up Connection

    var io = require('socket.io').listen(server);

    io.sockets.on('connection', function(socket){
        console.log('New Socket Connection: ', socket.id);

        socket.on('join_room', function(data){
            if (!rooms[data.name]){
                rooms[data.name] = {};
                rooms[data.name].name = data.name;
                rooms[data.name].users = [{user: data.user, socketid: socket.id}];
                io.emit('update_rooms', {action: 'create', name: data.name});
            }
            socket.join(data.name);
            io.to(data.name).emit('update_users', {name: data.name, user: data.user, socketid: socket.id});
            console.log('updated users to ',data.name);
        })

        socket.on('exit_room', function(data){
            socket.leave(data.name);
            if (rooms[data.name].users.length === 0) {
                io.emit('update_rooms', {action: 'destroy', name: data.name});
            }
        })

        socket.on('new_message', function(data){
            io.to(data.room).emit('update_chat', {name: data.room, user: data.user, message: data.message});
            console.log('sent new message to', data.room);
        })
    });

}
这是Angular应用程序。在为套接字设置的工厂中,我最初尝试了注释代码,后来才回来测试直接返回套接字。效果是一样的

var dojoChat = angular.module('dojoChat', []);

dojoChat.factory('socket', function ($rootScope) {
  var socket = io.connect();
  // return {
  //   on: function (eventName, callback) {
  //     socket.on(eventName, function () {  
  //       var args = arguments;
  //       $rootScope.$apply(function () {
  //         callback.apply(socket, args);
  //       });
  //     });
  //   },
  //   emit: function (eventName, data, callback) {
  //    console.log(data);
  //     socket.emit(eventName, data, function () {
  //       var args = arguments;
  //       $rootScope.$apply(function () {
  //         if (callback) {
  //           callback.apply(socket, args);
  //         }
  //       });
  //     })
  //   },
  //   sock: socket
  // };
  return socket;
});

dojoChat.factory('dojoChatFactory', function($http, socket){

    var rooms = {};
    var currentRoom;
    var user;

    var factory = {};

    factory.currentRoom = function(callback){
        callback(currentRoom);
    };

    factory.retrieveRooms = function(callback){
        callback(rooms);
    };

    factory.userName = function(callback){
        callback(user);
    };

    socket.on('update_rooms', function(data) {
        if (data.action = 'create') {
            rooms[data.name] = {name: data.name};
        } else if (data.action = 'destroy') {
            delete rooms[data.name];
        }
    });

    return factory;

})

dojoChat.controller('chatCtrl', function($scope, socket, dojoChatFactory){

    $scope.joined = {};
    $scope.current = '';

    $scope.user = '';

    $scope.sendMessage = function() {
        console.log('sendMessage:');
        console.log($scope.user);
        console.log($scope.joined[$scope.current]);
        socket.emit('new_message', {message: $scope.newMessage, user: $scope.user, room: $scope.joined[$scope.current].name});
        $scope.newMessage = '';
    };

    $scope.exitRoom = function() {
        delete $scope.joined[room];
        socket.emit('exit_room', {name: room, user: $scope.user});
    }

    $scope.setUserName = function(){
        $scope.user = $scope.userName;
        // dojoChatFactory.userName(function(user){
        //  user = $scope.userName;
        // })
    }

    $scope.getLocalUserName = function(){
        console.log($scope.user);
    }

    socket.on('update_chat', function(data) {
        console.log('update_chat', data);
        $scope.joined[data.name].messages.push({user: data.user, message: data.message});
    });

    socket.on('update_users', function(data) {
        if (!$scope.joined[data.name]){
            $scope.joined[data.name] = {};
            $scope.joined[data.name].users = [{user: data.user, socketid: data.socketid}];
            $scope.joined[data.name].messages = [];
            $scope.current = data.name;
        } else {
            $scope.joined[data.name].users.push({user: data.user, socketid: data.socketid});
        }
    });

    socket.on('update_room', function(data){
        $scope.current = data.name;
        if (!$scope.joined[data.name]){
            $scope.joined[data.name].name = data.name;
            $scope.joined[data.name].users = [];
            $scope.joined[data.name].messages = [];
        }
    })

});

dojoChat.controller('roomCtrl', function($scope, socket, dojoChatFactory){

    $scope.rooms = [];

    $scope.joinRoom = function(){
        dojoChatFactory.currentRoom(function(currentRoom){
            currentRoom = $scope.room;
            dojoChatFactory.userName(function(user){
                socket.emit('join_room', {name: currentRoom, user: user});
            })
        })
    };

    $scope.retrieveRooms = function(){
        dojoChatFactory.retrieveRooms(function(rooms){
            $scope.rooms = rooms;
        })
    };

})

服务器代码是什么样子的?你能同时发布整个Angle controller文件吗?服务器代码是什么样子的?你能同时发布整个Angle controller文件吗?