Node.js + AngularJS + Socket.io:推送的数据在控制器中不可用

Posted

技术标签:

【中文标题】Node.js + AngularJS + Socket.io:推送的数据在控制器中不可用【英文标题】:Node.js + AngularJS + Socket.io : pushed data not available in the controller 【发布时间】:2012-11-14 13:54:33 【问题描述】:

我已经设置我的节点服务器以随机间隔推出一些数据,并且数据正在到达客户端/浏览器;但是,我不知道如何在我的应用控制器中访问它。

#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()

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

alert: 
    id: 258,
    lat:    -95.20933,
    long:   37.027676,
    neighbourhood: "Downtown",
    time:   //stringified js timestamp

下面的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

但是,我不知道如何在我的控制器中访问来自 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'];

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

顺便说一句,我是基于 a tutorial 由 AngularJS 实习生编写的。不同的部分有相同的名称,所以我很难弄清楚每个不同的部分做了什么(而且它在 Jade 中也没有帮助)。

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

【问题讨论】:

【参考方案1】:

在您的 onemit 函数中,您正在使用:

socket.on(event, function() 
  $rootScope.$apply(function() 
    callback.apply(socket, arguments);
  );
);

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

socket.on(eventName, function()   
  var args = arguments;
  $rootScope.$apply(function () 
    callback.apply(socket, args);
  );
);

var args = arguments 很重要,因为它将args 设置为传递给socket.on 的回调的参数(这是您要查找的数据)。如果没有这一步,当你实际使用arguments 时,它会解析为传递给$rootScope.$apply 回调的参数(这是一个Angular 范围according to the documentation,解释了为什么你会得到控制台输出)。

解决方案是在对$apply 的调用之外捕获参数并将它们传递到您的回调中:

socket.on(event, function() 
  var args = arguments;
  $rootScope.$apply(function() 
    callback.apply(socket, args);
  );
);

【讨论】:

哦,天哪,现在说得通了。我想知道他为什么费心分配参数只使用一次。我会在早上试试。谢谢! 顺便说一句,@btford,谢谢你的教程! (但请不要用相同的名字命名不同的东西)

以上是关于Node.js + AngularJS + Socket.io:推送的数据在控制器中不可用的主要内容,如果未能解决你的问题,请参考以下文章

Node.js/AngularJS 前端调用 Spring Boot API 后端

在 Node.js 中部署 angularjs 应用程序

Hogan Js 和 AngularJs 与 Node Js

Angularjs,我无法运行 node.js 服务器文件

《Node.js+MongoDB+AngularJS Web开发》读书笔记及联想

Node.js & AngularJS 最快最简单的方式来实现认证和授权机制