2016-12-09 1 views
5

Mittlere Entwicklung Ich entschied mich für eine bessere Kontrolle auf das serverseitige Rendering zu wechseln amongst other benefits. Meine Web-Anwendung ist vollständig AJAX basiert, keine URL-Umleitung, so dass die Idee hier ist eine Website, die sich selbstWas ist der richtige Weg, um JavaScript-Code mit gerenderten HTTP an einen Client zu senden?

Ich konnte einfach nicht herausfinden, die richtige Art und Weise zu senden Javascript Ereignisse/Funktionen zusammen mit dem HTML-String, oder Sollte das notwendige Javascript immer in den statischen Dateien vorinstalliert sein?

Sagen wir mal Client eine klickt ‚offenen Tisch‘ vorgerenderter Taste

Der Server eine Abfrage machen, die HTML-Tabelle erstellen und senden es zurück, aber diese Tabelle muss auch JavaScript-Trigger und Funktionen richtig arbeiten, Wie werden diese gesendet, empfangen und ausgeführt?

Es gibt ein paar Artikel, die erwähnen, eval() nicht in Javascript zu verwenden, gibt es einen Weg um dies zu umgehen? Ich will nicht unnötig Ereignisse für Elemente vorzuladen haben, die noch nicht

Der Server vorhanden ist Python und der Kunde ist Javascript/JQuery

Theoretische Beispiel:

Kundenstamm Javascript:

$("body").on("click", "#open_table", function() { 

    $.getJSON('/get_table', function(response){ 

     $("#table_div").append(response.html); 
     eval(response.javascript()); //?? 
    } 
}); 

Python Server (views.py):

def get_table(request): 
    data = {} 
    #String containing rendered html 
    data['html'] = get_render_table() 
    #String containing Javascript code? 
    data['javascript'] = TABLE_EVENTS_JAVASCRIPT 
    return HttpResponse(json.dumps(data),content_type='json') 

meine Frage Bemerkenswert stammt aus einer experimentellen/Perspektive Lernen

+0

Warum benötigt die Antwort unterschiedliche Auslöser von der ursprünglichen Seite? Normalerweise würden Sie Trigger für Elemente nach Klasse festlegen, und das neue HTML würde Elemente mit diesen Klassen enthalten, um die Trigger automatisch aufzunehmen. –

+0

@DanielRoseman Meistens experimentell, in meinen Gedanken, warum sollte ich ein Ereignis für etwas laden, das (noch) nicht existiert und vielleicht nicht existiert? Das wird problematisch, wenn Ihre Website nur eine Seite ist. – Mojimi

+1

Wie ich verstehe, eval() ist vielleicht keine gute Idee, weil: 1) es ist relativ langsam, 2) es ist potenziell gefährlich. Aber wenn das JS, das vom Server kommt, nur einfache Trigger ist und immer von einer sicheren Quelle kommt, scheint es nicht falsch zu sein. –

Antwort

6

Update:

Sie jQuery.getScript() zu faul Last JS verwenden können. Ich denke, diese Lösung ist so nah wie möglich, um JS auszuführen, ohne eval() zu verwenden.

dieses Beispiel Siehe:

jQuery.getScript("/path/to/script.js", function(data, textStatus, jqxhr) { 
    /* Code has been loaded and executed. */ 
    console.log(data); // Data returned 
    console.log(textStatus); // Success 
    console.log(jqxhr.status); // 200 
    console.log("Load was performed."); 
}); 

und "/path/to/script.js" eine Zeichenfolge von $ .getJOSN Antwort zurückgegeben werden könnte.

Auch die Dokumentation für getScrippt() enthält Beispiele zum Umgang mit Fehlern und Cache-Dateien.

Alte Antwort:

Mit .on() Ereignisse auf aktuelle und zukünftige DOM-Elemente legt. Sie können Ereignisse nach dem Einfügen des DOMs entweder vor dem DOM-Einfügen oder nach dem Ereignis attache anhängen.

So in Ihrem Beispiel können Sie so etwas wie tun:

$("body").on("click", "#open_table", function() { 
$.getJSON('/get_table', function(response){ 
var code = $(response.html); 
    code.find(".elementToFind").on("click", function(){ 
// Code to be executed on click event 
}); 
    $("#table_div").append(code); 
} 
}); 

ich den Code nicht getestet, aber ich denke, es sollte funktionieren.

+1

Nun, "Code auf Click-Ereignis ausgeführt werden" ist, was der Server senden sollte. – Mojimi

+0

Ich aktualisierte meine Antwort mit einem besseren Ansatz. –

+0

Es scheint, dass dies der richtige Ansatz ist, indem man '$ .getScript (...)' verwendet, wie im Update beschrieben – ochi

1

Angenommen, Sie können nicht nur eine Ereignisbindungsfunktion einrichten und sie dann über das Hauptskript aufrufen (das JavaScript, das Sie benötigen, kann z. B. im Voraus nicht erraten werden), ist ein einfacher Weg Hängen Sie das JavaScript an den unteren Rand des zurückgegebenen HTML-Inhalts in den Skript-Tags an.Wenn es zusammen mit dem HTML angehängt wird, sollte das Skript einfach ausgeführt werden, ohne dass eval() benötigt wird.

Ich kann nicht schwören, dass dies in alten Browsern funktionieren würde, aber es ist ein Trick, den ich ein paar Mal verwendet habe, und ich hatte keine Probleme damit in Firefox, Chrome oder einem der späteren IE Versionen.

+0

Dies ist sicherlich eine interessante und einfache Lösung. – Mojimi

1

Ich denke, ich sehe, was Sie hier fragen, von meinem Verständnis wollen Sie die neue "Seite" asynchron senden und das neue Javascript und HTML rendern. Es sieht so aus, als hättest du deine Anfrage schon beantwortet, also werde ich nicht über das Senden von JSON-Objekten und das ganze How-To des Sendens von HTML und Javascript reden, weil es aussieht, als hättest du diesen Teil bekommen. Zu tun, was Sie wollen und dynamisch Ihre javascript in dieser Stackoverflow Frage wie sieht es hat, was Sie brauchen Is there a way to create a function from a string with javascript?

So zu Ihrem Beispiel betrifft, ist hier, wie es aussehen würde, wenn Sie die JSON-String aus dem Python empfangen Skript:

$("body").on("click", "#open_table", function() { 

    $.getJSON('/get_table', function(response){ 

     $("#table_div").append(response.html); 

     /* Create function from string */ 
     var newFunction = Function(response.javascript['param_1'], response.javascript['param_2'], response.javascript['function']); 

     /* Execute our new function to test it */ 
     newFunction(); 

    } 
}); 

* Ihre eigentliche Funktion Inhalt würde die Zeichenfolge: response.javascript['function']
* Ihre Parameternamen, wenn jeder in getrennten Strings ex wäre: response.javascript['param_1']

das heißt fast eine direkte Kopie des "String to function" -Codes, den Sie in der verknüpften Frage sehen können, ersetzte sie einfach durch Ihren relevanten Code. Dieser Code geht auch davon aus, dass Ihr Objekt mit dem Objekt response.javascript gesendet wird, das ein Array mit Ihren tatsächlichen Funktionsinhalt und Parameternamen enthält. Ich bin sicher, dass Sie den tatsächlichen Namen der var auch ändern könnten, oder vielleicht in einem assoziativen Array oder etwas, das Sie verfolgen und umbenennen können. Alle nur Vorschläge, aber hoffentlich funktioniert das für Sie und hilft Ihnen bei Ihrem Problem.

1

Ich mache auch ähnliche Arbeit in meinem Projekt, wo ich Teil HTML mit Ajax-Aufrufe laden musste und dann diese Teil-HTML-Elemente hat, die Ereignisse erfordert angehängt werden. Meine Lösung besteht also darin, eine allgemeine Methode zu erstellen, um Ajax-Aufrufe zu machen und einen Js-Methodennamen zu behalten, der nach einem Ajax-Aufruf in der HTML-Antwort selbst ausgeführt wird. Zum Beispiel mein Server wieder unter html

<input type="hidden" data-act="onPartialLoad" value="createTableEvents" /> 
 
<div>.........rest of html response.....<div>

nun gemeinsam Verfahren, suchen Sie nach Eingabe [type = 'hidden'] [Daten-act = 'onPartialLoad'] und für jeden Lauf des Verfahrens Name Wert Attribut versehen (value = "createTableEvents")

Dont Verwenden Eval() Methode, da sie nicht aufgrund von Sicherheits Probleme empfohlen. Check here.

Sie können die js-Methode mit dem Fenster ["Methodenname"] ausführen ... also hier ist ein Teil des Codes, den ich verwende.

$.ajax(options).done(function (data) { 
 
       
 
       var $target = $("#table_div");  
 
       $target.fadeOut(function() { 
 
        $target.html(data); 
 
        $target.fadeIn(function() { 
 
         try { 
 

 
          $('input[data-act="onPartialLoad"]', $target).each(function() { 
 
           try { 
 
            //you can pass parameters in json format from server to be passed into your js method 
 
            var params = $(this).attr('params'); 
 
            if (params == undefined) { 
 
             window[$(this).val()](); 
 
            } 
 
            else { 
 
             window[$(this).val()]($.parseJSON(htmlutil.htmlDecode(params))); 
 
            } 
 
           } catch (e) { 
 
            if (console && console.log) { 
 
             console.log(e.stack); 
 
             console.log($(this).val()); 
 
            } 
 
           } 
 
          }); 
 
         } 
 
         catch (e) { 
 
          console.log(e.stack); 
 
         } 
 
        }); 
 
       }); 
 
      });

Verwendung jQuery.getScript() (wie von Kalimah Apps vorgeschlagen) die ersten js Dateien erforderlich zu laden.

Verwandte Themen