2010-12-14 32 views
5

Tôi chỉ muốn tải ứng dụng GWT bằng cách thêm thẻ tập lệnh vào DOM, tuy nhiên vì trình liên kết GWT sử dụng document.write() Tôi không thể tìm được cách làm tốt nào vì thế. Tôi đã tìm thấy một số hack để làm như vậy trên các bài đăng trên blog khác nhau nhưng tất cả dường như không thành công với phiên bản GWT mới nhất. Bất kỳ cách tiếp cận không xâm lấn hợp lý nào để làm điều này đến với tâm trí?GWT bookmarket hoặc GWT như một thư viện bên ngoài

Làm rõ:

cách bình thường để khởi động một ứng dụng GWT, trong trang html máy chủ của bạn:

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

này, tất nhiên, khởi động ngay sau khi tải trang. Tôi muốn làm điều đó tại một thời điểm sau:

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

Tôi vô cùng xin lỗi nhưng bạn có thể vui lòng nói lại cho rõ. Một ví dụ sẽ giúp ích. – Amey

+0

@Amey kiểm tra cập nhật ở trên. Cảm ơn! –

+0

Đoạn mã của bạn sẽ hoạt động miễn là bạn đang thực thi đoạn mã trên trang web của mình. 'nocache.js' tải một tệp' cache.html' khi cần dựa trên ràng buộc hoãn lại và có thể không sử dụng URL tuyệt đối. –

Trả lời

5

Dưới đây là những gì có vẻ để làm việc cho đến nay:

Thêm phần này vào đầu App.gwt.xml của bạn:

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

Sau khi biên dịch ứng dụng của bạn với các thiết lập ở trên, sửa đổi (hoặc sao chép) các app.nocache.js tạo ra như sau:

1) bình luận các $doc.write... tuyên bố cuối cùng

2) Sao chép phần này từ $doc.write sta tement bạn chỉ cần nhận xét ra và đánh giá nó. Ví dụ:

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) Thêm dòng này ngay sau đó.

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

Vì vậy, về cơ bản, bạn thay thế $doc.write bằng hai dòng này.

Bây giờ, bookmarklet của bạn sẽ giống như thế:

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

Cập nhật: có vẻ như bạn thực sự có thể tránh tất cả điều này ngay bây giờ bằng cách sử dụng trình liên kết xsiframe thay thế! –

+0

Câu hỏi và thảo luận tuyệt vời Abdullah! Tôi đang cố gắng làm chính xác giống như bạn, thêm một GWT tạo JS từ một bookmarklet. Bạn có thể đưa cho tôi bất kỳ gợi ý nào cho liên kết xsiframe mà bạn đề cập đến ..... trong khi tôi đi và thử giải pháp của bạn được nêu ở trên. Cảm ơn! –

+0

Đây là mã cho trình liên kết 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

Bất cứ khi nào một trình duyệt tải một tập tin javascript, nó cũng thực hiện tất cả các dòng của nó inorder để xây dựng các bảng biểu tượng, vv

Trong trường hợp của bạn, ứng dụng tải trong trình duyệt và sau khi dom được tải, js mô-đun GWT của bạn được tải. Tại thời điểm này, trình duyệt sẽ cố gắng thực hiện mọi dòng của mô-đun GWT javascript, có thể làm cho DOM được tải trước đó của bạn đi tìm kiếm.

Trường hợp sử dụng của bạn chính xác là gì? Nếu yêu cầu của bạn đang có điều kiện nạp môđun GWT sau đó bạn có thể thử một cái gì đó như thế này: Bao gồm này trong đầu của bạn:

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

Ở đây, gwtmoduleloader.js là infact một servlet mà sẽ tổ chức logic để tìm ra nếu module gwt là Được nạp.

Nếu module GWT là được nạp, các sevlet có thể in một

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

hoặc nếu không trở lại âm thầm.

Khi trình duyệt đánh giá nội dung của gwtmoduleloader.js, nó có thể tìm thấy một document.write cho một tập lệnh khác (trong trường hợp của bạn là mô đun gwt), nó sẽ tải và đánh giá. Do đó, tải trọng có điều kiện và có thể đạt được trước khi cơ thể bắt đầu tải.

Đây có phải là những gì bạn đang tìm kiếm không?

+0

Tôi không biết tôi có thể làm rõ thêm bao nhiêu câu hỏi của mình, bạn có hiểu bookmarklet là gì không? Nó chèn javascript vào trang của bạn waaaaaaaaay sau khi trang đã được tải. Ví dụ: Trên trang stackoverflow này tôi đang đọc và nhìn xung quanh, và bây giờ tôi quyết định tôi muốn chạy bookmarklet của tôi. Tôi cần phải tiêm javascript vào trang. Trình tải của GWT sẽ không hoạt động vì sự kiện onload đã đến và đi trước đây, và document.write() sẽ không hoạt động nữa. –

1

Tôi giả sử bạn đã sử dụng trình liên kết tên miền chéo và điều này không giải quyết được vấn đề của bạn với document.write. Nếu không, nó có thể là giá trị một cái nhìn (xin lỗi, không đủ kinh nghiệm với nó để nói.)

Một cách tiếp cận rằng tôi khá chắc chắn có thể được thực hiện để làm việc là thế này:

bookmarklet bạn thêm một thẻ script đến trang (như bây giờ)

Tập lệnh này không phải là đầu ra trình biên dịch GWT. Đó là một javascript thuần cũ thêm một IFrame vào trang và src của IFrame đó được trỏ tới một trang HTML trên máy chủ của bạn tải mô-đun GWT của bạn.

Có lẽ mục tiêu là dành cho mô-đun GWT của bạn để đưa mọi thứ ra khỏi trang được tải vào. Tất nhiên, nó không thể làm điều này trực tiếp trong trường hợp này bởi vì IFrame đến từ một miền khác với trang mẹ.

Để thực hiện công việc này, bạn sẽ phải sử dụng cửa sổ.postMessage và window.addEventListener để giao tiếp giữa mô-đun GWT của bạn trong IFrame và lược khai javascript của bạn trong cha mẹ (sử dụng JSNI ở phía GWT.)

Nếu bạn phải hỗ trợ các trình duyệt cũ hơn, postMessage sẽ không hoạt động - nhưng bạn có thể có được với thao tác băm - nhưng đây có lẽ là nơi tôi muốn vẽ một đường về tính thực tiễn.

+0

Cảm nhận tốt nhờ. Tôi đã thực sự đưa ra một giải pháp mà dường như làm việc (tôi đã sử dụng xs linker). Về cơ bản, tôi đã thay thế một vài dòng trong tệp .nocache.js được tạo để chèn động một thẻ script thay vì làm điều doc.write. Tôi sẽ thử nghiệm nó nhiều hơn một chút trước khi tôi chắc chắn rằng nó hoạt động ... –

+0

Tuyệt vời. Dường như giải pháp "đúng" cho vấn đề này là viết một trình liên kết GWT làm những điều đúng - nhưng có vẻ như khả năng đó vẫn còn trong tương lai. –