简体   繁体   English

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

[英]Add GWT Widgets inside an iFrame in UIBinder?

I want to insert GWT Widgets like FlowPanel, HTMLPanel inside and iframe using GWT. 我想在其中使用GWT插入GWT小部件,例如FlowPanel,HTMLPanel和iframe。 I found this post which inserts content as a String into an iFrame. 我发现这篇文章将内容作为字符串插入到iFrame中。 But, this does not help when I want to integrate other panels and widgets. 但是,当我要集成其他面板和小部件时,这无济于事。

I find out how to insert GWT Widgets and Panels programmatically into GWT. 我发现了如何以编程方式将GWT小部件和面板插入GWT。 Here is how I do it: 这是我的方法:

  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

       }
    };
  }

My uiBinder: 我的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>

The former code inserts GWT Panels into an iframe. 前一个代码将GWT面板插入到iframe中。 The problem is that I cannot set any css style. 问题是我无法设置任何CSS样式。 Even if I set the style with: 即使我使用以下方式设置样式:

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

both variants do not work. 两种变体都不起作用。 I know I can inject a general css file in the head of the iframe document, but I want to use the GWT resources. 我知道我可以在iframe文档的开头插入一个普通的CSS文件,但是我想使用GWT资源。

How can I set the styles using CSS/GSS Resources for the Panels inside the iframe? 如何使用CSS / GSS资源为iframe内的面板设置样式?

I would suggest to add content to the iframe programmatically using IFrameElement and retrieving the iframe document with getContentDocument() in order to append the new content. 我建议使用IFrameElement以编程方式向iframe添加内容,并使用getContentDocument()检索iframe文档,以附加新内容。

By the way you can still use UIBinder like this, in your view.ui.xml: 顺便说一句,您仍然可以在view.ui.xml中像这样使用UIBinder:

 <iframe  ui:field="container"/>

and in your View.java: 并在您的View.java中:

 @UiField IFrameElement container;

About CSS I think the main issue is that iframe is like a sandbox and does not share information with the parent document. 关于CSS我认为主要问题是iframe就像一个沙箱,并且不与父文档共享信息。 My best guess is that you should clone your <link/> or <style/> element from the parent and append it into the <head/> of the child. 我最好的猜测是应该从父级克隆<link/><style/>元素,并将其附加到子级的<head/>中。

The final solution is: 最终的解决方案是:

    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);
        }
    });

The event listener is necessary in order to retrieve the document from the iframe you should wait the frame to load it, even if it is an about:blank . 为了从iframe检索文档,必须使用事件侦听器,即使它是about:blank ,您也应该等待框架加载它。

An <iframe> can't contain child elements (they'll be ignored) since it's effectively a browser window nested in your document. <iframe>不能包含子元素(它们将被忽略),因为它实际上是嵌套在文档中的浏览器窗口。 You have to use its src attribute to specify a resource to load. 您必须使用其src属性来指定要加载的资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM