在UIBinder的iFrame中添加GWT小部件?

时间:2016-01-04 16:25:17

标签: javascript java html iframe gwt

我想使用GWT插入FlowPanel,HTMLPanel里面和iframe等GWT Widgets。我找到了this帖子,它将内容作为字符串插入到iFrame中。但是,当我想要集成其他面板和小部件时,这没有用。

我找到了如何以编程方式将GWT Widgets和Panel插入GWT。我是这样做的:

  public interface Resources extends ClientBundle {

    @Source({Css.DEFAULT_CSS})
    Css css();

  }

  public interface Css extends CssResource {

    String DEFAULT_CSS = "test/client/app/start/StartView.gss";

    String outerBox();
    String iframe();
    String test();

  }

  @UiField(provided = true)
  Resources resources;

  @UiField(provided = true)
  Messages messages;

  @Inject
  public StartView(final Binder binder, Resources resources, Messages messages)    
  {
    this.resources = resources;
    resources.css().ensureInjected();
    this.messages = messages;
    initWidget(binder.createAndBindUi(this));

    final IFrameElement iframe = Document.get().createIFrameElement();
    FlowPanel innerBox = new FlowPanel() {
       @Override
       protected void onLoad() {
         super.onLoad();

         FlowPanel p1 = new FlowPanel();
         p1.addStyleName(resources.css().test());

         HTMLPanel panel = new HTMLPanel("Hello World!");
         panel.setStyleName(resources.css().test());  // does not work
         p1.add(panel);

         final Document doc = iframe.getContentDocument();
         BodyElement body = doc.getBody();

         body.appendChild(p1.getElement());
         panel.setStyleName(resources.css().test());  // does not work
         p1.getElement().addClassName(resources.css().test()); // does not work

       }
    };
  }

我的uiBinder:

<ui:with type="test.client.app.start.StartView.Resources" field="resources" />
<ui:with type="test.client.messages.Messages" field="messages" />

<g:FlowPanel ui:field="outerPanel" addStyleNames="{resources.css.outerBox}">
</g:FlowPanel>

前一代码将GWT面板插入iframe。问题是我无法设置任何CSS样式。即使我将样式设置为:

panel.setStyleName(resources.css().test());  // does not work
p1.getElement().addClassName(resources.css().test()); // does not work

两种变体都不起作用。我知道我可以在iframe文档的头部注入一个通用的css文件,但我想使用GWT资源。

如何使用CSS / GSS资源为iframe中的面板设置样式?

2 个答案:

答案 0 :(得分:2)

我建议使用IFrameElement以编程方式向iframe添加内容,并使用getContentDocument()检索iframe文档,以便附加新内容。

顺便说一下,你仍然可以在view.ui.xml:

中使用这样的UIBinder
 <iframe  ui:field="container"/>

并在你的View.java中:

 @UiField IFrameElement container;

关于CSS我认为主要问题是iframe就像一个沙盒,并且不与父文档共享信息。我最好的猜测是你应该从父母那里克隆你的<link/><style/>元素并将其附加到孩子的<head/>

最终的解决方案是:

    Event.sinkEvents(iframe, Event.ONLOAD);
    Event.setEventListener(iframe, new EventListener() {
        @Override
        public void onBrowserEvent(Event event) {
            StyleElement style = Document.get().createStyleElement();
            style.setInnerText(resources.css().getText());
            iframe.getContentDocument().getHead().appendChild(style);

            ParagraphElement pEl = Document.get().createPElement();
            pEl.setInnerText("Hallo World");
            pEl.addClassName(resources.css().whatever());
            iframe.getContentDocument().getBody().appendChild(pEl);
        }
    });

事件监听器是必要的,以便从iframe中检索文档,您应该等待框架加载它,即使它是 about:blank

答案 1 :(得分:0)

<iframe>不能包含子元素(它们将被忽略),因为它实际上是嵌套在文档中的浏览器窗口。您必须使用其src属性来指定要加载的资源。