Moritz: JavaScript für Fortgeschrittene

Hi zusammen,

ich baue grad Ajax in unser Webframework ein. An Komponenten in diesem Framework können sog. "JS-Listener" gehängt werden. Listener haben 3 String-Parameter:
1. den event ("onclick" etc.)
2. beliebigen Code der hinter den Event gerendert wird, also z.B. onclick="<hier der code>"
3. beliebigen (längeren) Code auf den meist von "onclick" zugegriffen wird, also z.b. ne Funktion.

Angenommen der Anwendungsentwickler hängt folgendes an

myComponent.addScriptListener(new JavaScriptListener(
    JavaScriptEvent.ON_CLICK,

"testFunction()",

"function testFunction() {" +
    "  alert('Test');" +
    "}" +
    "alert('Ich werde direkt ausgeführt!');"
));

wird die Komponente, vereinfacht gesagt, momentan wie folgt gerendert bzw. per XHR an den Client geschickt und dort ersetzt:

<tag id="xyz" onclick="testFunction()"><!-- weiteres html --></tag>

Gleichzeitig mit dem HTML-Code wird der JS-Code, den die Komponente benötigt (der 3. Parameter von oben), per XHR an den Client geschickt und dort per eval() ausgewertet.

Das problem mit dem Code im 3. Parameter ist, dass Funktionen die der Anwendungsentwickler so wie im Bsp. geschrieben hat, beim Evaluieren an kein Objekt im DOM angehängt werden. Sie sind also transient und im Bsp. geht deshalb der "onclick"-Aufruf von "testFunction()" ins Leere. Das wäre nicht der Fall wenn der Entwickler die Funktion so deklariert hätte: "self.testFunction = function() {...}". Dass er das weiß, kann ich aber nicht von ihm verlangen. Der 2. und 3. Parameter von JS-Listenern sind beliebige Strings.
Nun suche ich einen Mechanismus wie ICH es nachträglich machen kann, dass der im 3. Parameter definierte JS-Code bei eval(<code im 3. parameter>) an ein Objekt gebunden wird - entweder an self, oder noch besser an die Komponente "xyz" selber. Eingreifen kann ich dabei in den Rendering-Mechanimus um z.B. den JS-Code des Anwendungsentwicklers (2. + 3.) mit irgendwelchen eigenen JS-Konstrukten zu umgeben. Die Frage ist nur welche???

Hilft mir u.U. das hier weiter?

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply

Ich weiß irgendwie nix richtig damit anzufangen...

Danke,
Moritz

  1. Oder kürzer gefragt: Wenn ich folgenden Code als String habe

    function testFunction() {
      alert('Test');
    }
    alert('Ich werde direkt ausgeführt!');

    Wie kann ich den an "self" anhängen?

  2. Hallo,

    Gleichzeitig mit dem HTML-Code wird der JS-Code, den die Komponente benötigt (der 3. Parameter von oben), per XHR an den Client geschickt und dort per eval() ausgewertet.

    Das problem mit dem Code im 3. Parameter ist, dass Funktionen die der Anwendungsentwickler so wie im Bsp. geschrieben hat, beim Evaluieren an kein Objekt im DOM angehängt werden.

    Das verstehe ich nicht. Ein einfaches eval("function bla () {}"); erzeugt eine Methode window.bla, also eine globale Funktion, die wie üblich als Funktionsobjekt am window-Objekt hängt.

    Sie sind also transient und im Bsp. geht deshalb der "onclick"-Aufruf von "testFunction()" ins Leere. Das wäre nicht der Fall wenn der Entwickler die Funktion so deklariert hätte: "self.testFunction = function() {...}".

    Ist mir unverständlich, ob ich eval("window.func = function () {}") schreibe oder eval("function func () {}"), sollte m.W. ein identisches Resultat erzeugen.

    Hilft mir u.U. das hier weiter?

    http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Function:apply

    Jein. Gehen wir mal von der Schwestermethode call() aus:

    var obj = {};  
    var code  = "function func () {};";  
    window.eval.call(obj, code);  
    alert(obj.func + "\n" + window.func);
    

    Hier zwingst du eval() dazu, im Kontext von obj ausgeführt zu werden. func ist dann (theoretisch) eine Methode von obj anstatt von window.

    Problem: Das geht nur im Firefox. Im IE wird einfach window.func erzeugt. Dito im Konqueror. Opera sagt: »Illegal use of eval«. Also, die Möglichkeit kannst du vergessen.

    Mathias

    --
    »No nations, no borders.«
    SELFHTML Weblog