2010-12-14 16 views
5

Po prostu chcę załadować aplikację GWT dodając tag skryptu do DOM, jednak ponieważ linker GWT używa document.write() Nie jestem w stanie znaleźć żadnego dobrego sposobu robienia więc. Znalazłem kilka hacków do tego na różnych blogach, ale wszystkie wydają się nie działać z najnowszą wersją GWT. Czy przychodzi ci do głowy rozsądne, nieinwazyjne podejście?GWT bookmarket lub GWT jako biblioteka zewnętrzna

Wyjaśnienie:

normalny sposób, aby uruchomić aplikację GWT, w stronę html gospodarza:

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

To, oczywiście, rozpocznie się tak szybko, jak załadowaniu strony. Chcę zrobić to w późniejszym czasie:

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

mi niezmiernie przykro, ale czy mógłbyś przeformułować. Przykład pomógłby. – Amey

+0

@Amey Checkout aktualizacji powyżej. Dzięki! –

+0

Twój fragment kodu powinien działać tak długo, jak wykonujesz go w swojej witrynie. 'nocache.js' ładuje plik' cache.html' w razie potrzeby na podstawie odroczonego powiązania i prawdopodobnie nie używa bezwzględnego adresu URL. –

Odpowiedz

5

Oto, co wydaje się działać tak daleko:

Dodaj to do góry App.gwt.xml:

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

Po kompilacji swoją aplikację z powyższym ustawieniu modyfikować (lub skopiować) wygenerowane app.nocache.js następująco:

1) Komentarz ostatni $doc.write... oświadczenie

2) Skopiuj część z $doc.write STA po prostu skomentowałeś i sprawdziłeś to. Przykład:

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) Dodaj tę linię zaraz po.

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

Więc w zasadzie wymiany $doc.write z tymi dwoma liniami.

Teraz Twój bookmarklet będzie wyglądać mniej więcej tak:

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

Aktualizacja: wygląda na to, że możesz tego uniknąć teraz, po prostu używając zamiast tego linku xsiframe! –

+0

Doskonałe pytanie i dyskusja Abdullah! Próbuję zrobić dokładnie to samo, co ty, dodaj wygenerowany przez GWT JS ze skryptozakładki. Czy możesz podać mi jakieś wskazówki do linkera xsiframe, o którym wspomniałeś ..... podczas gdy ja wychodzę i wypróbowuję twoje rozwiązanie udokumentowane powyżej. Dzięki! –

+0

Oto kod linku xsiframe: http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker .java? r = 9161 –

0

Gdy przeglądarka ładuje plik JavaScript, jej również wykonać każdą linię niej Inorder zbudować tabele symboli itp

w przypadku, aplikację ładuje się w przeglądarce i po załadowaniu domeny ładuje się twój moduł GWT. W tym momencie przeglądarka spróbuje wykonać każdą linię Javy modułu GWT, co może spowodować, że Twój wcześniej załadowany DOM będzie działał podrzucany.

Jaki jest dokładnie twój przypadek użycia? Jeśli wymóg jest warunkowo załadowaniu modułu GWT to może twój spróbować czegoś takiego: uwzględnienie tego w swojej głowie:

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

Tutaj, gwtmoduleloader.js jest rzeczywiście aplet, który będzie trzymać logiki, aby dowiedzieć się, czy moduł GWT jest do załadowania.

Jeśli moduł GWT ma być załadowany, sevlet można wydrukować

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

albo wrócić po cichu.

Gdy przeglądarka ocenia zawartość pliku gwtmoduleloader.js, może znaleźć document.write dla innego skryptu (w twoim przypadku modułu gwt), który zostanie załadowany i oceniony. Jest to zatem obciążenie warunkowe, które można osiągnąć przed rozpoczęciem ładowania ciała.

Czy tego właśnie szukałeś?

+0

Nie wiem, o ile więcej mogę wyjaśnić moje pytanie, czy rozumiesz, czym jest bookmarklet? Wprowadza javascript na twoją stronę waaaaaaaay po załadowaniu strony. Przykład: na tej stronie stackoverflow czytam i rozglądam się, a teraz decyduję, że chcę uruchomić bookmarklet. Muszę wstrzyknąć javascript na stronę. Program ładujący GWT nie będzie działał, ponieważ zdarzenie onload pojawiło się i zniknęło eony temu, a funkcja document.write() przestanie działać. –

1

Zakładam, że już korzystasz z łącznika międzydomenowego i to nie rozwiąże problemu z plikiem document.write. Jeśli nie, to może być warte obejrzenia (przepraszam, nie wystarczy doświadczenie z nim powiedzieć.)

Jedno podejście, że jestem dość pewny może być wykonane do pracy to:

Twój bookmarklet dodaje tag skryptu do strony (jak teraz)

Ten skrypt nie jest wynikiem kompilatora GWT. Jest to zwykły javascript, który dodaje element IFrame do strony, a src tego IFrame jest wskazywany na stronie HTML serwera, która ładuje twój moduł GWT.

Prawdopodobnie celem jest, aby moduł GWT wydobywał dane ze strony, w której został załadowany. Oczywiście nie można tego zrobić bezpośrednio w tym przypadku, ponieważ ramka IFrame pochodzi z innej domeny niż strona nadrzędna.

Aby to zadziałało, musiałbyś użyć okna.postMessage i window.addEventListener do komunikacji między twoim modułem GWT w ramce IFrame a twoim skrótem javascript w katalogu nadrzędnym (przy użyciu JSNI po stronie GWT).

Jeśli musisz obsługiwać starsze przeglądarki, postMessage nie będzie działać - ale Ty może być w stanie uciec manipulacją hashami - ale to jest prawdopodobnie miejsce, w którym narysowałem linię praktyczności.

+0

Dobre komentarze dzięki. Wpadłem na rozwiązanie, które wydaje się działać (korzystałem z łącznika xs). Zasadniczo zamieniłem kilka linii w wygenerowanym pliku .nocache.js, aby dynamicznie wstawiać znacznik skryptu, zamiast robić rzecz doc.write. Mam zamiar przetestować to trochę dłużej, zanim jestem pewien, że to działa ... –

+0

Świetnie. Wydaje się, że "poprawnym" rozwiązaniem tego problemu byłoby napisanie linkera GWT, który robi właściwe rzeczy - ale wydaje się, że ta zdolność jest nadal w przyszłości. –