2012-04-13 12 views
3

Ich wickelte haben (Client-Seite) socket.io in einem Prototyp-Klasse:Original 'dieser' Kontext mit Socket.IO

Chat.Client = Class.create(); 

Chat.Client.prototype = { 

    initialize: function() { 
     ... 
     this.socket.on('message', this.on_message); 
     ... 
    }, 

    on_message: function(data) { 
     this.add_chat_message(data.something); 
    } 

    do_something: function(something) { 
     ... 
    } 

Dies, weil 'diese' funktioniert nicht in ON_MESSAGE wird 'SocketNamespace' . Traditionell würde ich das umgehen, indem ich "this" als zusätzlichen Parameter in den Callback übergebe, aber weil ich socket.io verwende, kann ich das nicht einfach tun.

Wie kann ich das lösen?

Antwort

9

Sie können es in einer anderen Funktion wickeln:

initialize: function() { 
    // ... 
    var client = this; 
    this.socket.on('message', function(data) { client.on_message(data); }); 

In neueren Browsern (oder Node.js) Sie können alternativ auch eine Funktion auf dem "bind" genannt Function Prototyp verwenden:

this.socket.on('message', this.on_message.bind(this)); 

Die "bind" -Funktion gibt eine Funktion zurück, die beim Aufruf die ursprüngliche Funktion ("on_message") mit dem angegebenen Wert als this-Wert aufrufen soll.

+0

Vielen Dank, binden wird funktionieren. (Jetzt muss ich nur 8 Minuten warten, um Ihre Antwort zu akzeptieren) –

+0

Ich bin froh, Ihnen zu helfen. – Pointy

+1

Kleiner Zusatz: Bekannte JS-Bibliotheken bieten verbindliche Funktionalität. Wenn man [subscore.js] (http://underscorejs.com) benutzt, gibt es eine Crossbinder 'bind' Funktion:' _.bind (function() {...}, this) '. Außerdem gibt es in jQuery die Funktion 'proxy', die dasselbe tut:' $ .proxy (function() {...}, this) '. Hier ist ein [Leistungstest mit Beispielen] (http://jsperf.com/bind-vs-jquery-proxy/5) für alle Möglichkeiten, dies zu tun. – HighCat