Node.js + AngularJS + Socket.io:推送控制器中没有的数据

jac*_*cob 5 javascript websocket node.js socket.io angularjs

我已经设置我的节点服务器以随机间隔推出一些数据,数据到达客户端/浏览器; 但是,我无法弄清楚如何在我的应用程序的控制器中访问它.

#node.js file: /server.js (truncated for brevity)

var http    = require('http').createServer(handler),//refers to handler()
    fs      = require('fs'),
    io      = require('socket.io').listen(http);
http.listen(8000);

…

io.sockets.on('connection', function (socket) {
    /* DUMMY CODE: this generates fake alerts at random intervals */
    (function loop() {
        var rand = Math…;
        …
        setTimeout(function(){
            …
            var alert = { … };

            socket.emit('alert', {
                "alert": alert
            });//socket.emit()

            loop();
        }, rand);
    }());
});//io.sockets.on()
Run Code Online (Sandbox Code Playgroud)

当我登录alert到终端时,它看起来像这样:

alert: {
    id: 258,
    lat:    -95.20933,
    long:   37.027676,
    neighbourhood: "Downtown",
    time:   //stringified js timestamp
}
Run Code Online (Sandbox Code Playgroud)

而arguments从下面包含了我想要的数据(基本相同alert).

# /app/js/services.js

angular.module( 'BAR.services' , [])
.factory('socketio', function($rootScope){

    var socket = io.connect();
    return {
        on: function(event, callback) {
            socket.on(event, function(){
                //console.log(arguments);
                $rootScope.$apply(function(){
                    callback.apply(socket, arguments);
                });//$rootScope.$apply()
            });//socket.on()
        },//on
        emit: function(event, data, callback) {
            socket.emit(event, data, function(){
                //console.log(arguments);
                $rootScope.$apply(function(){
                    if (callback) callback.apply(socket, arguments);
                });//$rootScope.$apply()
            });//socket.emit()
        },//emit
        disconnect: function() {
            socket.disconnect();
        }
    }//return

});// AlertServices
Run Code Online (Sandbox Code Playgroud)

但是,我无法弄清楚如何从arguments我的控制器中访问数据:

# /app/js/controllers.js

function Alerts( $scope , socketio ) {

    socketio.on('alert', function(data) {
        console.log(data);      /* I expect this to be the data I want */
        $scope.alert = data.alert;
    });

    $scope.disconnect = function(){
        socketio.disconnect();
    }

}
Alerts.$inject = ['$scope','socketio'];
Run Code Online (Sandbox Code Playgroud)

当我data在控制器中登录浏览器的控制台时,我得到了一个巨大的对象,似乎是它的父母$scope; 并且data.alert未定义.我也尝试指定第二个这样的参数,因为socketio.on('alert', function( data , args )它可能是arguments(因为callback.apply( … )在服务中有2个),但是当我这样做并将其记录到控制台时,args返回undefined.

顺便说一句,我是基于AngularJS实习生的教程.不同的部分有相同的名称,所以我有点麻烦弄清楚每个不同的peices做了什么(它也没有帮助它在Jade).

我真正想要做的是在视图中使用来自的数据更新绑定alert.

Mic*_*ley 5

在您on和emit函数中,您正在使用:

socket.on(event, function() {
  $rootScope.$apply(function() {
    callback.apply(socket, arguments);
  });
});
Run Code Online (Sandbox Code Playgroud)

但是在教程的原始版本中,它说:

socket.on(eventName, function() {  
  var args = arguments;
  $rootScope.$apply(function () {
    callback.apply(socket, args);
  });
});
Run Code Online (Sandbox Code Playgroud)

这var args = arguments很重要,因为它设置args为传递给回调的参数socket.on(这是您正在寻找的数据).如果没有这个步骤,当你真正使用arguments它时,它会解析为传递给回调的参数$rootScope.$apply(根据文档,这是一个Angular范围,解释了为什么你得到你做的控制台输出).

解决方案是捕获调用之外的参数$apply并将其传递给回调函数:

socket.on(event, function() {
  var args = arguments;
  $rootScope.$apply(function() {
    callback.apply(socket, args);
  });
});
Run Code Online (Sandbox Code Playgroud)

  • 这篇文章的作者:这是正确的答案. (2认同)