2010-12-14 11 views
5

ich einfach eine GWT App laden möge einen Skript-Tag auf das DOM fügt aber hinzu, weil der GWT-Linker verwendet document.write() Ich bin nicht in der Lage eine gute Möglichkeit, von zu finden tun damit. Ich habe einige Hacks dafür in verschiedenen Blogposts gefunden, aber sie scheinen alle mit der neuesten Version von GWT zu versagen. Irgendein einigermaßen nicht-invasiver Ansatz dafür kommt Ihnen in den Sinn?GWT Buchmarkt oder GWT als externe Bibliothek

Klarstellung:

Normalweg eine GWT-Anwendung, in der Host-HTML-Seite zu starten:

<script type="text/javascript" language="javascript" src="myapp.nocache.js"></script> 

Das ist natürlich beginnt, sobald die Seite geladen wird. Ich möchte es zu einem späteren Zeitpunkt tun:

function startapp() { 
    var head = document.getElementsByTagName('head'); 
    var s = document.createElement('script'); 
    s.setAttribute('type', 'text/javascript'); 
    s.setAttribute('src', 'myapp.nocache.js'); 
    head[0].appendChild(s); 
} 
+0

Ich bin sehr leid, aber könnten Sie bitte neu formulieren. Ein Beispiel würde helfen. – Amey

+0

@Amey Checkout das Update oben. Vielen Dank! –

+0

Ihr Code-Snippet sollte so lange funktionieren, wie Sie es auf Ihrer Site ausführen. 'nocache.js' lädt eine' cache.html' Datei nach Bedarf, basierend auf einer verzögerten Bindung, und verwendet wahrscheinlich keine absolute URL. –

Antwort

5

Hier ist, was bisher zu funktionieren scheint:

hinzufügen Zu Anfang Ihrer App.gwt.xml:

<!-- Cross site linker --> 
<inherits name="com.google.gwt.core.Core" /> 
<add-linker name="xs" /> 

Nach Ihrer Anwendung mit der obigen Einstellung Kompilieren, ändern (oder kopieren) Comment

1) die letzte Anweisung $doc.write...

2) Kopiere diesen Abschnitt von der $doc.write sta: die erzeugten app.nocache.js wie folgt Sie haben es gerade kommentiert und es bewertet. Beispiel:

eval('window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),' + 'type: "end"});' + 'window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "moduleStartup", millis:(new Date()).getTime(),' + 'type: "moduleRequested"});'); 

3) Fügen Sie diese Zeile direkt nach.

document.body.appendChild(document.createElement('script')).src=base + strongName + ".cache.js"; 

Sie sind also im Grunde ersetzt die $doc.write mit diesen beiden Linien.

Nun wird Ihr Bookmarklet in etwa so aussehen:

<a href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://abc.com/app.nocache.js';})();">My App</a> 
+0

Update: Sieht so aus, als könntest du das jetzt wirklich vermeiden, indem du einfach den xsiframe Linker benutzt! –

+0

Ausgezeichnete Frage und Diskussion Abdullah! Ich versuche genau dasselbe zu tun wie Sie, fügen Sie ein GWT generiertes JS aus einem Bookmarklet hinzu. Kannst du mir irgendwelche Hinweise auf den Xsiframe Linker geben, den du erwähnst ..... während ich ausgehe und deine oben dokumentierte Lösung versuche. Vielen Dank! –

+0

Hier ist der Code für den xsiframe-Linker: http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker .java? r = 9161 –

0

Jedes Mal, wenn ein Browser eine JavaScript-Datei lädt, der auch jede Zeile davon ausführen inorder die Symboltabellen usw.

In Ihrem Fall zu bauen, die App lädt im Browser und nachdem das dom geladen ist, wird Ihr GWT-Modul js geladen. An dieser Stelle wird der Browser versuchen, jede Zeile des GWT-Moduls Javascript auszuführen, was möglicherweise dazu führt, dass Ihr früher geladenes DOM zu einem Toss führt.

Was genau ist Ihr Anwendungsfall? Wenn Ihre Anforderung bedingt ist das GWT-Modul geladen, dann könnte Sie so etwas wie dies versucht: dies Fügen Sie in Ihrem Kopf:

<script src="gwtmoduleloader.js"></script> 

Hier gwtmoduleloader.js ist ein infact Servlet, das Logik halten, wenn das GWT-Modul, um herauszufinden, ist geladen sein.

Wenn das GWT-Modul geladen werden soll, kann die sevlet druckt ein

document.write('<script src="myapp.nocache.js"></script>') 

oder auch leise zurück.

Wenn der Browser den Inhalt von gwtmoduleloader.js auswertet, kann er ein document.write für ein anderes Skript finden (in Ihrem Fall das gwt-Modul), das geladen und ausgewertet wird. Dies ist somit eine bedingte Belastung und kann erreicht werden, bevor der Körper mit dem Laden beginnt.

Ist das wonach Sie gesucht haben?

+0

Ich weiß nicht, wie viel mehr ich meine Frage klären kann, verstehst du, was ein Bookmarklet ist? Es injiziert Javascript in Ihre Seite waaaaaaaaay, nachdem die Seite bereits geladen wurde. Beispiel: Auf dieser stackoverflow-Seite lese ich und schaue mich um, und jetzt entscheide ich, dass ich mein Bookmarklet ausführen möchte. Ich muss Javascript in die Seite injizieren. Der Ladevorgang von GWT wird nicht funktionieren, da das Onload-Ereignis vor Äonen gekommen und verschwunden ist und document.write() nicht mehr funktioniert. –

1

Ich nehme an, Sie sind bereits den Cross-Domain-Linker verwendet und dies Ihr Problem mit document.write nicht behoben. Wenn nicht, könnte es sich lohnen, einen Blick (sorry, damit nicht genug Erfahrung zu sagen.)

Ein Ansatz, den ich ziemlich sicher bin, könnte an die Arbeit gemacht werden, ist dies:

Ihr Bookmarklet fügt ein Skript-Tag auf der Seite (wie jetzt) ​​

Dieses Script Compiler Ausgabe nicht GWT. Es ist ein einfaches JavaScript, das der Seite einen IFrame hinzufügt und der src dieses IFrame auf eine HTML-Seite auf Ihrem Server zeigt, die Ihr GWT-Modul lädt.

Vermutlich ist das Ziel, für Ihr Modul GWT Dinge es in wurde von der Seite erhalten geladen. Dies kann natürlich in diesem Fall nicht direkt geschehen, da der IFrame aus einer anderen Domäne als der übergeordneten Seite stammt.

Um diese Arbeit zu machen Sie verwenden Fenster haben würde.postMessage und window.addEventListener zur Kommunikation zwischen Ihrem GWT-Modul im IFrame und Ihrem Javascript-Stub im Parent (JSNI auf der GWT-Seite).

Wenn Sie ältere Browser unterstützen müssen, funktioniert postMessage nicht - aber Sie könnte vielleicht mit der Hash-Manipulation davonkommen - aber das ist wahrscheinlich der Punkt, an dem ich auf die Zweckmäßigkeit eingehen würde.

+0

Gute Kommentare danke. Ich habe tatsächlich eine Lösung gefunden, die zu funktionieren scheint (ich benutzte den xs-Linker). Ich ersetzte im Wesentlichen ein paar Zeilen in der generierten .nocache.js, um ein Skript-Tag dynamisch einzufügen, anstatt doc.write zu machen. Ich werde es ein wenig mehr testen, bevor ich mir sicher bin, dass das funktioniert ... –

+0

Großartig. Es scheint, als wäre die "richtige" Lösung für dieses Problem, einen GWT-Linker zu schreiben, der die richtigen Dinge tut - aber es scheint, als ob diese Fähigkeit noch in der Zukunft liegt. –