2012-05-17 60 views
1

我正在使用GWT,我正在嘗試將谷歌地圖添加到我的網站。 因爲我想使用谷歌地圖V3我使用JSNI。 爲了在我的網站上顯示地圖,我需要創建一個id =「map」的div元素,並在地圖的初始化函數中獲取它。我這樣做了,它運行良好,但它在網頁上的位置很有趣,我希望它被附加到我在代碼中創建的面板上。 所以我的問題是我該怎麼做呢? 我可以用面板內的GWT以某種方式創建div嗎?在面板內添加div元素?

我試圖做的創建一個新的HTMLPanel這樣的:

runsPanel.add(new HTMLPanel("<div id=\"map\"></div>")); 

凡runsPanel是我想要的面板附加到。 然而,失敗的時候我用下面的初始化函數以檢索股利:

private native JavaScriptObject initializeMap() /*-{ 

    var latLng = new $wnd.google.maps.LatLng(31.974, 34.813); //around Rishon-LeTsiyon 
    var mapOptions = { 
     zoom : 14, 
     center : latLng, 
     mapTypeId : $wnd.google.maps.MapTypeId.ROADMAP 
    }; 
    var mapDiv = $doc.getElementById('map'); 
    if (mapDiv == null) { 
     alert("MapDiv is null!"); 
    } 
    var map = new $wnd.google.maps.Map(mapDiv, mapOptions); 
    return map; 

}-*/; 

(它會彈出警告 - 「MapDiv爲空!」)

任何想法? 謝謝

+1

爲什麼不使用GWT-Google-API預發佈版本:http://code.google.com/p/gwt-google-apis/issues/detail?id=381#c53? –

+0

你的'runsPanel'是什麼類型的?當然你可以在面板內創建一個'div'。在你的代碼中,所有的都是正確的。它應該正常工作。 – kapand

+0

其Horizo​​ntalPanel。然而,它不起作用.... –

回答

2

您需要確保initializeMap()在加載時被調用,以驗證DOM元素是否可訪問。

嘗試,並刷新你的方法,並使用其它技術來創建地圖面板:

  1. 擴展Widget定義將被用於谷歌地圖容器中的自定義部件:

    public class MapPanel extends Widget { 
    
        private Element container; 
    
        public MapPanel() { 
    
         container = DOM.createDiv(); 
         container.setId("map"); 
    
         // this is required by the Widget API to define the underlying element 
         setElement(container); 
        } 
    
        @Override 
        protected void onLoad() { 
         super.onLoad(); 
    
          initializeMap(); 
         } 
        } 
    } 
    
  2. 調用初始化:

    runsPanel.add(new MapPanel()); 
    

還有其他問題,如id屬性,在JSNI方法中強制編碼並強制重複代碼,以及initializeMap()的合適位置以及是否爲JSNI層創建覆蓋類型,但這不在此範圍之內。

參考文獻:

0

您可能要簡化使用UiBinder的事情;請參閱這裏的Hello World示例:https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder

UiBinder允許您編寫定義UI佈局結構的XML,與使用HTML佈局頁面的方式類似。然而,XML可以構造小部件,例如按鈕等。此外,您可以將名稱附加到XML元素,並在您的Java代碼中引用它以將事件處理程序綁定到它,等等。它工作的很好,它使代碼非常簡單讀書。但是,在這些情況下,UiBinder可以爲您製作原生HTML元素並以您想要的方式嵌套它們,而不必調用方法來製作小部件並將它們放入其他小部件中。此外,然而,UiBinder的文件說,UiBinder的可以做到使用瀏覽器的代表事物的本土方式,理應得到更高效的代碼(從上面的鏈接)的一個更好的工作:

除了是一個更自然,簡潔的方式來構建你的UI比 通過代碼來完成它,UiBinder還可以讓你的應用程序更高效。 瀏覽器通過將HTML的大字符串 填充到innerHTML屬性中比通過一堆API調用更好地構建DOM結構。 UiBinder很自然地利用了這一點,其結果是構建應用程序的最愉快的方式也是構建它的最佳方式。

我覺得這個功能可能會讓瀏覽器更有可能正確地註冊你的小部件,以便稍後通過getElementById()找到它們。

你上面的代碼可能是這樣的UiBinder的:

<g:HTMLPanel ui:field='my_HTMLPanel'> 
    <div ui:field='map_div'> 
    <!-- put some HTML here --> 
    </div> 
</g:HTMLPanel> 
1

你的代碼工作正常,如果您確保調用initializeMap之前runsPanel附加到DOM()。

你可以用這個簡單的入口點測試:

@Override 
public void onModuleLoad() { 

    final Panel runsPanel = new ...Panel; /* Use the kind of panel you like */ 

    runsPanel.add(new HTMLPanel("<div id=\"map\"></div>")); 

    RootLayoutPanel.get().add(runsPanel); 

    initializeMap(); 
} 

這是不夠的HTMLPanel添加到runsPanel。如果runsPanel本身沒有連接到DOM,那麼$doc.getElementById('map')找不到任何東西。

注意:請確保以某種方式設置「地圖」div的高度,否則您將看不到地圖。