2012-11-27 25 views
5

ランダムな間隔でいくつかのデータをプッシュし、データがクライアント/ブラウザに到達するようにノードサーバーをセットアップしました。しかし、私はどのように私のアプリのコントローラでそれにアクセスするかを把握することはできません。Node.js + AngularJS + Socket.io:コントローラにプッシュされたデータがありません

#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は未定義です。私もarguments(サービスではcallback.apply(…)は2であるので)socketio.on('alert', function(data , args)と思っていましたが、コンソールに記録したときにargsが返されました。

Btw、これはAngularJS internによってa tutorialに基づいています。異なった部分には同じ名前がついていたので、それぞれの部分が何をしたのかを調べるのに少し苦労しました。

私が実際にやりたいことは、ビュー内のバインディングをalertのデータで更新することです。あなたのonemit機能で

答えて

5

、あなたが使用している:

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として、重要ですコールバックに渡された引数にargssocket.on(探しているデータ)に設定します。この手順を行わないと、実際にargumentsを使用すると、コールバックに渡された引数が$rootScope.$apply(これは角度範囲according to the documentation)に解決され、コンソール出力を取得する理由が説明されます。

ソリューションは、$applyへのコールの外の引数をキャプチャし、あなたのコールバックにそれらを渡すために、次のようになります。

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

おやっ私のああ、今それが理にかなっています。私はなぜそれを一度だけ使うように議論をつけるのに悩まされたのだろうと思っていました。私は朝にそれを試みます。ありがとう! – jacob

+2

こちらの記事の著者:これは正しい答えです。 – btford

+0

ハズザ!出来た。ありがとう! – jacob

関連する問題