Eventhandling und Parameter

- javascript
1 molily
Hello out there!
Vereinfachter Code:
// aus molilys Artikel Organisation von JavaScripten
// [link:http://aktuell.de.selfhtml.org/artikel/javascript/organisation]
Function.prototype.bindAsEventListener = function (object) {
var method = this;
var wrapper = function (event) {
method.call(object, event || window.event);
};
return wrapper;
};
function bar(n) {
alert("Output: " + n);
}
function Foo(n) {
this.value = n;
var button = document.createElement("button");
document.body.appendChild(button);
button.appendChild(document.createTextNode("Click me!"));
button.onclick = window.bar.bindAsEventListener(this.value);
}
window.onload = function() {
var foo = new Foo(42);
}
So geht’s nicht; es wird "Output: [object MouseEvent]" ausgegeben.
Wie übergebe ich 'this.value' aus Foo an die Funktion bar?
(Es soll im Script viele Instanzen von Foo geben.)
See ya up the road,
Gunnar
Hallo,
bindAsEventListener() erwartet als Parameter ein Objekt, in dessen Kontext die Funktion ausgeführt werden soll. Daher ist lediglich das Schema this.func.bindAsEventListener(this) sinnvoll.
bindAsEventListener() erfüllt nur einen Zweck: Den Handler im Kontext eines bestimmten Objektes ausführen. Man kann auf diese Weise *nicht* Objekte an den Handler durchreichen. Die Handler-Funktion bekommt als Parameter immer nur das Event-Objekt.
Wie übergebe ich 'this.value' aus Foo an die Funktion bar?
Gar nicht.
Idealerweise ist bar eine Methode von Foo und value eine Eigenschaft der Instanz.
Dann macht man:
function Foo (n) {
// Private Methode
function bar () {
// Zugriff auf die Instanz über this und darüber auf die benötigte Eigenschaft
alert(this.value);
// (Oder auch einfach alert(n), weil bar hier als Closure wirkt. Pfiffig!)
}
// Initialisiere
this.value = n;
var button = document.createElement("button");
document.body.appendChild(button);
button.appendChild(document.createTextNode("Click me!"));
button.onclick = this.bar.bindAsEventListener(this);
}
window.onload = function() {
var foo = new Foo(42);
}
Andernfalls siehe etwa https://forum.selfhtml.org/?t=138533&m=900197.
Mathias
button.onclick = this.bar.bindAsEventListener(this);
Das muss natürlich bar.bindAsEventListener heißen, schließlich ist es eine private Methode.
Die Frage, wie man am besten Daten an eine Handler-Funktion übergibt, kann man eigentlich nicht allgemein beantworten, weil es sehr auf die konkrete Anwendung ankommt, welche Methode die beste ist. Wie sieht also dein Originalcode aus, für was steht Foo, was macht bar und was hat es mit n auf sich? Kann bar als Methode von Foo gesehen werden?
Wenn bar unbedingt eine globale Funktion bleiben soll (warum auch immer - objektorientiert und lose globale Funktionen gemischt erscheint erst einmal unsauber), bieten sich andere Möglichkeiten an. Bei diesen Lösungen mit Closures ist es unwichtig, ob func eine private Methode ist oder global notiert wurde:
function Konstruktor (param) {
...
elem.onclick = function closure () { func(param); };
}
Wenn es denn unbedingt eine öffentliche Eigenschaft sein soll:
function Konstruktor (param) {
...
this.eigenschaft = param;
var self = this;
elem.onclick = function closure () { func(self.param); };
}
Der Name closure ist optional und hat keine Bedeutung/Wirkung, ich habe ihn hier lediglich zum Verständnis des Codes eingefügt. Es handelt sich weiterhin um eine als Function-Expression notierte anonyme Funktion.
Letzteres Beispiel zeigt zur Hälfte das, was auch bindAsEventListener() macht.
Mathias
Hi molily,
danke für deine Ausführungen.
für was steht Foo,
Für das GUI: eine Tabelle mit anclickbaren Zellen; je nachdem, wo geclickt wird, führt das System verschiedene Dinge aus.
was macht bar
Die Daten ändern. Ich dachte, die Daten wären ein anderes Objekt.
und was hat es mit n auf sich?
Es sind sogar zwei Parameter: Zeilen- und Spaltennummer der angeclickten Zelle.
Kann bar als Methode von Foo gesehen werden?
Ich dachte, bar wäre eher eine Methode des Datenobjektes.
(warum auch immer - objektorientiert und lose globale Funktionen gemischt erscheint erst einmal unsauber)
Ja. Ich wollte es „sauber“ programmieren. Bin aber zu dem Schluss gekommen, dass ich mir jetzt die akademische Reinheit zeitlich nicht leisten kann und werde es wohl prozedural programmieren – aus Gewohnheit.
See ya up the road,
Gunnar