在面板中添加div元素?

时间:2012-05-17 20:29:58

标签: javascript google-maps gwt google-maps-api-3 jsni

我正在使用GWT,我正在尝试将google-maps添加到我的网站。 由于我想使用google-maps V3,我使用的是JSNI。 为了在我的网站上显示地图,我需要创建一个id =“map”的div元素,并在地图的初始化函数中获取它。我这样做了,它的效果很好,但它在网页上的位置很有趣,我希望它能附加到我在代码中创建的面板上。 所以我的问题是我该怎么做? 我可以在面板中使用GWT以某种方式创建一个div吗?

我试图像这样创建一个新的HTMLPanel:

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

其中runsPanel是我想要附加到的面板。 然而,当我使用以下初始化函数时,它无法检索div:

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为空!”)

有什么想法吗? 谢谢

3 个答案:

答案 0 :(得分:2)

您需要确保在加载时调用initializeMap(),以验证DOM元素是否可访问。

尝试并刷新您的方法并使用其他技术来创建地图面板:

  1. 扩展Widget以定义将用于Google地图容器的自定义窗口小部件:

    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());
    
  3. 还有其他问题,例如id属性,在JSNI方法中硬编码并强制重复代码,以及initializeMap()的正确位置以及是否为JSNI创建叠加类型图层,但这不在此范围内。

    <强>参考文献:

答案 1 :(得分:1)

如果确保在调用initializeMap()之前将runsPanel附加到DOM,则代码可以正常工作。

您可以使用这个简单的EntryPoint进行测试:

@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的高度,否则您将看不到地图。

答案 2 :(得分: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还可以提高您的应用程序效率。   浏览器通过填充大字符串更好地构建DOM结构   将HTML转换为innerHTML属性而不是一堆API调用。   UiBinder自然而然地利用了这一点,结果就是这样   构建应用程序最愉快的方式也是构建应用程序的最佳方式。

我认为此功能可能会使浏览器更有可能正确注册您的小部件,以便稍后通过getElementById()找到它们。

您的上述代码在UiBinder中可能如下所示:

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