2015-10-28 32 views
1

對JavaScript而言,我相當陌生,我一直對我認爲是全局變量的範圍存在問題。傳遞數據時發生JavaScript變量作用域問題

這裏就是我通過Socket.IO接收來自用戶的數據:(server.js)

var locationData = {lat: '-20', long: '20'}; 
var latNumber; 
var longNumber; 

//SocketIO data 
var chat = require('express')(); 
var http = require('http').Server(chat); 
var io = require('socket.io')(http); 

io.sockets.on('connection', function (socket) { 
    socket.on('new message', function (msg) { 
     locationData = msg; 
     latNumber = parseFloat(locationData.lat); 
     longNumber = parseFloat(locationData.long); 
     io.emit('message', msg.message); 
    }); 
}); 

http.listen(5670, function(){ 
    console.log('listening on *:5670'); 
}); 

io.on('connection', function(socket){ 
    console.log('a user connected'); 
    socket.on('disconnect', function(){ 
     console.log('user disconnected'); 
    }); 
}); 

function getLat(){ 
    return latNumber; 
} 
function getLong(){ 
    return latNumber; 
} 

下面是HTML的腳本,我想接收數據:(HelloWorld.html的)

 <script type="text/javascript" src="/server.js"></script> 
    <script> 
    var viewer = new Cesium.Viewer('cesiumContainer'); 
    var citizensBankPark = viewer.entities.add({ 
     name : 'Test', 
     position : Cesium.Cartesian3.fromDegrees(getLat(),getLong()), 
     point : { 
      pixelSize : 5, 
      color : Cesium.Color.RED, 
      outlineColor : Cesium.Color.WHITE, 
      outlineWidth : 2 
     }, 
     label : { 
      text : 'Test', 
      font : '14pt monospace', 
      style: Cesium.LabelStyle.FILL_AND_OUTLINE, 
      outlineWidth : 2, 
      verticalOrigin : Cesium.VerticalOrigin.BOTTOM, 
      pixelOffset : new Cesium.Cartesian2(0, -9) 
     } 
    }); 

    viewer.zoomTo(viewer.entities); 
</script> 

我試圖從latNumber和longNumber中讀取數據,並在server.js中定義並設置爲HelloWorld.html中的位置分配。我遇到的問題是,一旦數據到達HelloWorld.html,它是未定義的,並在瀏覽器中給出錯誤。

現在我不確定的是爲什麼它沒有定義。記錄server.js中的latNumber和longNumber變量可以正常工作,並在其中包含數據。同時將getLat()getLong()中的返回語句更改爲硬編碼變量(如15)可以正常工作,並將其傳遞到HelloWorld.html,然後執行它應該執行的操作。只有將兩者結合在一起纔會出錯!

任何幫助或指針將不勝感激!謝謝!

回答

1

這裏有很多問題。您的server.js文件看起來不像客戶端代碼,它看起來應該是通過Node.js運行服務器。您是否使用Node.js運行server.js以偵聽端口5670,如此代碼所示?

如果是這樣,不錯,但擺脫客戶端代碼<script src="/server.js">參考。你不希望客戶端讀取服務器的源代碼(理想情況下,它不應該被服務,但這是一個不同的話題)。

所以,現在你有一個新的問題:你的服務器有getLatgetLon函數在客戶端上根本不存在。您需要將信息從服務器傳輸到客戶端。

在server.js,你可以添加一些代碼,使通過REST提供這些數字:

chat.get('/location', function(req, res, next) { 
    var response = { 
     lat: latNumber, 
     lon: lonNumber 
    }; 
    res.type('application/json'); 
    res.send(JSON.stringify(response)); 
}); 

此服務器的代碼將監聽的URL /location請求,並與包含數字的JSON字符串響應。

接下來,您的客戶端代碼應該異步地從服務器請求這些值(這意味着我們在等待服務器響應時不會鎖定瀏覽器的UI)。這是像這樣做:

var viewer = new Cesium.Viewer('cesiumContainer'); 

Cesium.loadJson('/location').then(function(data) { 
    viewer.entities.add({ 
     name : 'Test', 
     position : Cesium.Cartesian3.fromDegrees(data.lon, data.lat), 
     point : { 
      pixelSize : 5, 
      color : Cesium.Color.RED, 
      outlineColor : Cesium.Color.WHITE, 
      outlineWidth : 2 
     }, 
     label : { 
      text : 'Test', 
      font : '14pt monospace', 
      style: Cesium.LabelStyle.FILL_AND_OUTLINE, 
      outlineWidth : 2, 
      verticalOrigin : Cesium.VerticalOrigin.BOTTOM, 
      pixelOffset : new Cesium.Cartesian2(0, -9) 
     } 
    }); 

    viewer.zoomTo(viewer.entities); 
}); 

在上面的代碼,loadJson返回一個承諾來獲取數據,我們添加一個回調函數時承諾解決執行。該回調接收服務器的數據作爲參數,並構建一個新的實體。你可以看到實體的位置是基於從服務器收到的數據。

如果服務器對位置的想法發生變化,您可能需要讓客戶端定期輪詢新位置,或者您可以使用多種不同的技術(長輪詢,服務器端推送,EventSourceWebSockets,等等)讓客戶更新。但對於初學者,只需重新加載客戶端頁面即可查看新位置。

+0

是的,它運行在一個節點上。js服務器實例。忘了提及!我會試着玩這個,讓你知道它是怎麼回事。 – SirFerret

+0

我遇到的唯一問題是瀏覽器中記錄的404錯誤,因爲找不到/位置。我向根添加了一個位置文件夾,它仍然出現。查找關於loadJson的更多信息,試圖找出它不想工作的原因。 – SirFerret

+0

編輯server.js後,您是否停止並重新啓動節點服務器?磁盤上不應該有任何「位置」文件夾。上面第一個代碼塊中的代碼指示節點如何通過返回位置數據而不是文件夾來響應「位置」Web請求。 – emackey