[Prototype] OOP-Event-Handling

tobias_petry

Erfahrenes Mitglied
Hallo, ich wollte mal meinen JS-Code umbauen auf OOP mit Prototype (1.6), da gibt es natürlich das Problem OOP und JS ^^

also ich möchte auf Events reagieren, da habe ich mein Anliegen nun mal ganz versimpelt und es sieht so aus:
Code:
PetryNewMedia = Class.create();
PetryNewMedia.prototype = {
  initialize: function() {
    document.observe("dom:loaded", this.initAll);
  },

  initAll: function() {
    alert('huhu');
    $('stoneage_greybox').observe('click', this.slide);
  },
  
  slide: function(event) {
    //doAll
    alert('hehe');
    Event.stop(event);
  }
};

Das Alert mit dem huhu kommt noch, kein Problem, jedoch kann ich den Event-Handler nicht setzen, dass er eine Methode in dieser Klasse aufrufen soll (this.slide) und nicht einfach eine Funktion, wie in allen Beispielen.
Einfache Funktionen sind kein Problem, aber ich möchte es ja OOP umsetzen, hoffe mir kann da jemand helfen.

Btw.: Ist es irgendwie auch möglich Parameter an die Event-Funktion zu übergeben? Das wäre zum Teil ganz nützlich :)
 
Naja zum Thema OOP und JS , ich selber nutz das Prototype Framework gar nicht ist nicht so mein Ding aber jedem das selbe.

Also
Code:
function myfunction () {
 
    function nametoupper () {
    }    

    this.getName = function () {
    }
}
myfunction.prototype = {
    setname:function () {
    }
}

das sind nun 3 Verschiedene Funktionen die 3 verschiedene Sichtbereiche haben.
nametoupper ist eine "private" Methode. Auf die bekommst von aussen keinen Zugriff.

getName ist eine priviligierte Methode diese hat auch zugriff auf die privaten Methoden.

setName ist eine nicht priviligierte Methode damit bekommst keinen Zugriff auf die privaten Methoden/Eigenschaften sondern nur auf die priviligierten methoden oder alle öffentlichen Eigenschaften.

Was dein Codebeispiel angeht

Code:
    function myfunction () {
    }

    myfunction.prototype = {
         addEvent:function () {
               document.getElementById('name').addEventListener('click',myfunction.catchEvent,false);
// das würde nicht im IE nun gehen
         },
         catchEvent:function (evt) {
             alert("hier");
         }
    }

das wichtige hier daran das der this Operator nicht mehr funktioniert , man muss die Funktionen über den Namen myfunction ansprechen.

Zum Thema Variablen mit übergeben , ginge dies schon

Code:
    function myfunction () {
    }

    myfunction.prototype = {
         addEvent:function () {
               document.getElementById('name').addEventListener('click',catchEvent,false);
               // das würde nicht im IE nun gehen
              
              function catchEvent () {
                 myfunction.catchEvent.call(myfunction.catchEvent,parameter1,parameter2...);
              }
          },
         catchEvent:function (args) {
             args[0] == parameter 1 
             args[1] == parameter 2
             args[n] == parameter n
         }
    }

Was man hiebei beachten sollte über call , der erste Paramater bei call gibt an in welchen Objekt man sich befindet und wird sozusagen nicht weiter gereicht.Sollte dort zum Beispiel nicht myfunction.catchEvent stehen sondern this.
Dann befinden wir uns in der Funktion catchEvent im Event Objekt.
 
Habs mitlerweile geschafft, Prototype überlädt die this-Eigenschaft in Methoden die per Event aufgerufen werden, musste das fixen :-(
 
Naja nicht wirklich , wenn du den Event startest und eine Funktion zurück angibst die den Event auffängt bist Du nicht mehr in deinen Ursprünglichen Objekt sondern im Event Objekt.

Darum funktioniert da auch dann das this nicht mehr wie gewünscht aber vollkommen richtig eigentlich.
Das Event Objekt kennt deine Methoden und Variablen nicht dafür stellt es eigene zur Verfügung.

auszustesten kannst es mit
Code:
function eventcapture () {
   for(key in this) alert(key+" "+this[key]);
}

Um das zu verhindern verwendet man Closures oder aber man verzichtet auf das this und nimmt den Namen des Objektes in deinen Fall war es dann wohl

PetryNewMedia.methodenName
 
Hallo Tobias,

damit this in den Methoden erhalten bleibt, musst du die Referenz auf die Methode erst an ein Objekt binden. Das passiert in Prototype mit bindAsEventListener und sähe in deinem Fall so aus:

Code:
PetryNewMedia = Class.create();
PetryNewMedia.prototype = {
  initialize: function() {
    document.observe("dom:loaded", this.initAll.bindAsEventListener(this));
  },

  initAll: function() {
    alert('huhu');
    $('stoneage_greybox').observe('click', this.slide.bindAsEventListener(this, 1, 2));
  },
  
  slide: function(event, arg1, arg2) {
    //doAll
    alert('hehe');
    alert(arg1);
    alert(arg2);
    Event.stop(event);
  }
};
Wie man sieht, kann man damit auch gleich das Problem mit der Übergabe von zusätzlichen Argumenten lösen.

Grüße,
Matthias
 
Danke Matthias ja, so hatte ich es auch gelöst, haben ne halbe Stunde im prototype irc chat diskutiert bis einem einfiel, dass das prototype (ich meine nur das neue) die this-eigenschaft überlädt.

Aber supi, das sich hier einige so gut auskennen :)
 
Zurück