manolo / gwt-polymer-elements

Polymer Web Components for GWT. A collection of Material Design widgets for desktop and mobile.
Apache License 2.0
155 stars 49 forks source link

Error when using custom element as root UiBinder element #72

Closed ReeceGoddard closed 8 years ago

ReeceGoddard commented 8 years ago

I'm trying to use a custom element for the root of a UiBinder XML but I'm getting this compile error

Invoking generator com.google.gwt.uibinder.rebind.UiBinderGenerator
    [ERROR] Illegal field name "f_cw-dialog1"

Using DivElement does not return this error.

Hello.ui.xml

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
    <cw-dialog>
        <p>Test Content</p>
        <actions>
            <button>Save</button>
        </actions>
    </cw-dialog>
</ui:UiBinder>

Hello.java

public class Hello {
    interface HelloUiBinder extends UiBinder<CwDialogElement, Hello> {}

    private static HelloUiBinder uiBinder = GWT.create(HelloUiBinder.class);

    private CwDialogElement root;

    public Hello() {
        root = uiBinder.createAndBindUi(this);

        Polymer.importHref(CwDialogElement.SRC);
    }
}
manolo commented 8 years ago

what is cw-dialog ? what happens if you use a as the first element in your UI ?

ReeceGoddard commented 8 years ago

cw-dialog is my own custom element. But that's not the issue here. The same problem occurred when I tried to use paper-button as the root element.

It compiles and runs fine if I change the root element to be a native element, such as:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
    <div>
        <cw-dialog>
            <p>Test Content</p>
            <actions>
                <button>Save</button>
            </actions>
        </cw-dialog>
    </div>
</ui:UiBinder>

But I don't want the unnecessary div wrapping my element.

amirtoole commented 8 years ago

Got this working with the following switch (UiBinder interface must be of type Element and then cast to our custom element). It's not extremely graceful, but does do what we were attempting.

    interface TestDialogUiBinder extends UiBinder<Element, TestDialog> {
    }

    public TestDialog() {
        root = (CwDialogElement) binder.createAndBindUi(this);
        Polymer.importHref(CwDialogElement.SRC);
        Polymer.whenReady((Function) f -> {
            root.show();
            return null;
        });
    }
manolo commented 8 years ago

Gotcha, normally the easiest way is to wrap the component in an HTMLPanel, which allows having any kind of childs: widgets, elements and custom elements, this can be helpful http://www.gwtproject.org/doc/latest/polymer-tutorial/widgets-buildui.html

Otherwise you need the casting. GWT ui-binder might evolution to support webcomponents directly but right now we have to deal with its constrains