0

これはスコープ/変数アクセスの問題だと思いますが、よくわからないので、コンテキスト全体を説明します。

アイデアは、socket.io経由でサーバーに送信され、mongooseでmongodbに保存されるHTMLフロントエンドに数値を入力できるnode.js-「アプリケーション」を持つことです。そして、代わりにデータベースから番号を取得し、それをクライアント側スクリプトで処理します。

実際の例では、クライアント側で車の走行距離などを入力し、この情報を node.js サーバーに転送する socket.io イベントを起動し、mongoose を使用して monogodb に保存することができます。それはうまくいきます。ここで、いくつかの設定を保持して保存できるようにしたいとします。変数 numDigits といくつかのメソッド/関数を保持
するオブジェクトがあります。 サーバーへの保存は機能し、サーバーからのエントリのクエリは機能します。 ただし、番号をに保存することはできません。 Preferences
numDigits
Preferences.numDigits

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();
});

サーバー.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) {
            ...
        }*/

クライアント側のコンソール出力は次のとおりです。

(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"

UI.build() の for ループも起動しないので、「デフォルト」もある値を取得します。前述のように、変数/スコープの問題がどこかにあると確信していますがPreferences.get();、自分で問題を理解することはできません。あなたの誰かがそれについて私を助けることができれば、それはあまりにも素晴らしいことです.

よろしくお願いします!

編集:間違ったコードを貼り付けました

4

1 に答える 1

1

あなたのコードはまだその出力を生成したものではないと思います(つまり、コードの12行目と14行目の両方に#1が含まれています。とにかく、それはおそらく問題ではありません。

OK、最初に、「emit」の2番目のパラメーターは送信するデータであり、3番目のパラメーターのみがコールバック関数である必要があります。しかし、おそらくこれは機能します。

次に、スコープの問題。クロージャ(=コールバック関数)で「this」が何を指しているかに常に注意してください。最善の解決策は次のとおりです。

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

},

私自身、メンバー関数の最初の行は常に「var that = this」であり、関数全体で「that」のみを参照します。本当に理由を知りたい場合は、説明を確認してください。また、コード全体で「use strict」を使用すると、この種の問題を防ぐのに役立ちます。

私はそれを試していませんが、これは役立つはずだと思います。

于 2012-10-21T14:39:16.980 に答える