2012-11-27 12 views
5

Ho installato il mio server di nodo per spingere fuori alcuni dati a intervalli casuali, ei dati vengono sempre al cliente/navigatore; tuttavia, non riesco a capire come accedervi nel controller della mia app.Node.js + AngularJS + Socket.io: spinto dati non disponibili nel controller

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

Quando accedo alert al Terminal, sembra che questo:

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

E arguments dal basso contiene i dati che voglio (sostanzialmente uguale a 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 

Tuttavia, non riesco a capire come accedere ai dati da arguments nel mio controller:

# /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']; 

Quando accedo data alla console del browser qui nel controller, ottengo un enorme oggetto che sembra essere il genitore di $scope; e data.alert non è definito. Ho anche cercato di specificare un secondo parametro come questo socketio.on('alert', function(data , args) pensando che potrebbe essere arguments (dal callback.apply(…) nei servizi è 2), ma quando l'ho fatto e sono collegato a consolare, args tornato indefinito.

Btw, ho basato questo su a tutorial da una stagista AngularJS. Diversi pezzi avevano lo stesso nome, quindi ho avuto un po 'di problemi nel capire cosa facevano i vari pezzetti (inoltre non era utile che fosse in Jade).

Quello che voglio fare è aggiornare un legame a mio avviso con i dati alert.

risposta

5

Nei tuoi on e emit funzioni, si sta utilizzando:

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

ma nella versione originale di questo dal tutorial, si dice:

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

Il var args = arguments è importante, in quanto imposta args sugli argomenti passati alla richiamata su socket.on (che sono i dati che stai cercando). Senza questo passaggio, quando si utilizza effettivamente arguments, viene risolto gli argomenti passati nella richiamata a $rootScope.$apply (che è uno scope angolare according to the documentation, che spiega perché si ottiene l'output della console).

La soluzione potrebbe essere quella di catturare gli argomenti al di fuori della chiamata alla $apply e superare quelli nella vostra callback:

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

Oh mio Dio, ora che ha un senso. Mi stavo chiedendo perché si sia preso la briga di assegnare argomenti per usarlo solo una volta. Ci proverò la mattina. Grazie! – jacob

+2

Autore di quell'articolo qui: questa è la risposta giusta. – btford

+0

Hazzaaah! Ha funzionato. Grazie! – jacob