简体   繁体   English

node.js / socket.io中的对象/方法/变量访问

[英]Object/Method/Variabe access in node.js/socket.io

I believe this is some scope/variable access issue but I am not sure about it so I am going to tell you the whole context. 我相信这是一个范围/变量访问问题,但是我不确定,因此我将告诉您整个情况。

The idea is to have a node.js-"application" which lets you enter a number in a HTML frontend which is sent to the server via socket.io and then saved to mongodb with mongoose. 这个想法是要有一个node.js-“应用程序”,它允许您在HTML前端中输入一个数字,该数字通过socket.io发送到服务器,然后与猫鼬一起保存到mongodb。 And then, in return to get the number from the database and do something with it in the client-side script. 然后,作为回报,从数据库中获取数字并在客户端脚本中对其进行处理。

A real-life example would be that you are able to enter the mileage of your car/whatever on the clientside, then fire a socket.io event that transfers this information to the node.js server and save it there to monogodb using mongoose. 一个现实的例子是,您可以在客户端输入汽车/任何车辆的行驶里程,然后触发socket.io事件,该事件会将此信息传输到node.js服务器,并使用猫鼬将其保存到monogodb。 That works. 这样可行。 Now say I also want to be able to keep and save some preferences. 现在说我也希望能够保留并保存一些首选项。
I have a Preferences object that keeps the variable numDigits and some methods/functions. 我有一个Preferences对象,该对象保留变量numDigits和一些方法/功能。
Saving numDigits to the server works, querying the entry from the server works. numDigits保存到服务器有效,从服务器查询条目。
However, saving the number into Preferences.numDigits does not. 但是,将数字保存到Preferences.numDigits不会。

client.js client.js

//init.js
//var Preferences;

var Preferences = {
    numDigits: 'default',
    parse: function(){
        this.numDigits = parseInt($('#preferences > #num-digits').val());
    },
    get: function(){
        socket.emit('req-preferences', function(responseData) {
            this.numDigits = responseData.numDigits;
            console.log('#1: ' + this.numDigits);
        });
        console.log('#1: ' + this.numDigits);
        // 2 different outputs (scopes?) here

    },
    save: function(){
        socket.emit('save-preferences', this);
    }
}

var UI = {
    numDigits: Preferences.numDigits,
    build: function() {
        Preferences.get();
        console.log(Preferences.numDigits);
        for (i=0; i<Preferences.numDigits;i++) {
            $('#input-km').append('<input type="text"></input>');
        }   
    }
}

$(document).ready(function() {

    socket = io.connect('http://127.0.0.1:8080');


    function print(data) {
        console.log(data);
        if (data.length == 0) {
            $('#results').html('no entries!');
        } else {
            for (i = 0; i < data.length; i++) {
                $('#results').append(data[i].date + ' - ' + data[i].km + '<br />');
            }   
        }
    }

    socket.on('res-entries', function(entries){
        print(entries);
    });

    $('#submit').click(function() {
        var kmStand = $('#km').val();
        socket.emit('submit', kmStand, function(){
        });
    });

    $('#req-entries').click(function(){
        socket.emit('req-entries', function() {
        });
    });


    $('#remove-all').click(function() {
        socket.emit('remove-all', function() {
            console.log('remove all');
        });
    });

    $('#save-preferences').click(function() {
        Preferences.parse();
        Preferences.save();
    });

    //Preferences.get();
    UI.build();
});

server.js server.js

var http = require('http');
var connect = require('connect');
var io = require('socket.io');
var mongoose = require('mongoose');

var server = http.createServer(connect()
    .use(connect.static(__dirname))).listen(8080);

var socket = io.listen(server);
socket.set('log level', 2);

var db = mongoose.createConnection('localhost', 'mileagedb');
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {

    var entrySchema = new mongoose.Schema({
        km: String,
        date: {
            type:Date, 
            default:Date.now
        }
    });

    var preferencesSchema = new mongoose.Schema({
        numDigits: Number,
        objId: Number
    });

    var Preferences = db.model('Preferences', preferencesSchema);

    var Entry = db.model('Entry', entrySchema);

    socket.sockets.on('connection', function(socket){ 

        socket.on('submit', function(kmStand){
            var eintrag = new Entry({
                km: kmStand,
            });

            eintrag.save(function(err) {
                if (err) {
                    console.log('error while saving');
                } else {
                    console.log('saved');
                }
            });

            Entry.find(function(err, entries) {
                console.log('all entries:');
                console.log(entries);
            });
        });

        socket.on('req-entries', function() {
            Entry.find(function(err, entries) {
                socket.emit('res-entries', entries);
            });
        });

        socket.on('remove-all', function() {
            Entry.find().remove();
            Preferences.find().remove();
        });

        socket.on('save-preferences', function(prefObj) {

            Preferences.update(Preferences.findOne(), {$set: { numDigits: prefObj.numDigits }}, { upsert: true }, function(err){
                if (err) {
                    console.log('error saving');
                }
            });

            Preferences.find(function(err, prefs) {
                console.log('all preferences:');
                console.log(prefs);
            });
        });

        socket.on('req-preferences', function(fn) {
            Preferences.findOne(function(err, prefs) {
                fn(prefs);
            })
        });

    });
});



/* maybe:
socket.on('get-entries'), function(requestSpecification) {
            ...
        }*/

The console output on the client side is: 客户端上的控制台输出为:

(on body load, UI.build() fires)
#2: default (line 14)
#1: 5 (line 12)

>Preferences.get();
#2: default (line 14)
<-undefined
#1: 5 (line 12)

>Preferences.numDigits
"default"

the for-loop in UI.build() also doesnt fire so I take the value it has there is "default" too. UI.build()中的for循环也不会触发,因此我也将其取值为“ default”。 As mentioned before, I am pretty sure it is a variable/scope issue somewhere in Preferences.get(); 如前所述,我很确定这是Preferences.get();某个位置的变量/作用域问题Preferences.get(); but I just cant understand the problem on my own. 但是我自己无法理解问题。 It would be too nice if someone of you could help me out on that. 如果你们中的某人可以帮助我,那太好了。

Thanks a lot in advance! 在此先多谢!

edit: pasted wrong code 编辑:粘贴错误的代码

I think your code is still not the one that generated that output (ie both line 12 and 14 in the code contain #1. Anyways, that's probably not the issue. 我认为您的代码仍然不是生成该输出的代码(即代码中的第12行和第14行都包含#1。无论如何,这可能不是问题。

OK, firstly, I though that the second parameter to "emit" should be the data to send, and only the third should be the callback function. 好的,首先,我虽然要“发送”的第二个参数应该是要发送的数据,而只有第三个参数应该是回调函数。 But perhaps this does work. 但这也许确实有效。

Then the scoping issue. 然后是范围界定问题。 Always be careful with what "this" points to in closures (=callback functions). 务必小心闭包中的“ this”所指向的内容(=回调函数)。 Best solution would be: 最好的解决方案是:

get: function(){
    var that = this;
    socket.emit('req-preferences', function(responseData) {
        that.numDigits = responseData.numDigits;
        console.log('#1: ' + that.numDigits);
    });
    console.log('#1: ' + that.numDigits);
    // 2 different outputs (scopes?) here

},

Myself, I always have the first line of any member function be "var that = this", and then only refer to "that" throughout the function. 我自己,我总是让任何成员函数的第一行是“ var that = this”,然后在整个函数中仅引用“ that”。 If you really want to learn why, check the description . 如果您真的想了解原因,请查看说明 Also, using "use strict" throughout your code can help prevent these kinds of problems. 另外,在整个代码中使用“严格使用”可以帮助防止此类问题。

I haven't tried it, but I would think this should help. 我没有尝试过,但是我认为这应该有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM