Binding Components from a PolymerTemplate

You can add child components to templates using the Component or Element API.

Note
Added items to the PolymerTemplate only show up on screen if added to the ShadowRoot of the template if it doesn’t have a <slot> see. Using <slot> in PolymerTemplates

By using the @Id annotation, you can get a server-side Component or Element, for an element only defined in the PolymerTemplate html file for the client side to use on the server.

Note
The Component/Element needs to have the same @Tag as the actual element that is wired. This means that you can not wire a <span id="content"></span> to a @Id("content") Div content

Here is the content of the HTML template file which has a placeholder div element with a "content" identifier. This element is mapped to a Div component in Java code below to set a Component as a child for it.

<dom-module id="main-page">
    <template>
        <div id="header">Main page</div>
        <div id="content"></div>
        <hr>
        <div id="footer">
            <a href="mailto:someone@example.com?Subject=Hello%20again" target="_top">Send Mail</a>
        </div>
    </template>

    <script>
        class MainPage extends Polymer.Element {
            static get is() {
                return 'main-page'
            }
        }
        customElements.define(MainPage.is, MainPage);
    </script>
</dom-module>

You can implement the method that wires a Component to the content of your template element.

@Tag("main-page")
@HtmlImport("/com/example/MainPage.html")
public class MainPage extends PolymerTemplate<TemplateModel> {

    @Id("content")
    private Div content;

    public void setContent(Component content) {
        this.content.removeAll();
        this.content.add(content);
    }
}

The @Id annotation is used to map a component to an element created by the template on the client that has the identifier "content".

A component instance of the declared type is created automatically and wired to the actual dom element and injected into the 'container' field.

Now you can set any Component as a content for the MainPage class:

MainPage page = new MainPage();
page.setContent(new Label("Hello!"));

In the Polymer template class example above, the div element with "footer" identifier could also be mapped via Div component and @Id("footer") annotation. But neither its hierarchical structure nor attributes/properties are available on the server side via API. The injected Div instance doesn’t have any server side child even though there is the anchor a element available on the client side. The injected instance getChildren() method returns an empty Stream.

Similar to this the getText() method of the Div instance injected via @Id("header") returns an empty string.

So server side Component/Element read methods are not always in sync with the client-side. But you still may use mutation API methods from the server side like appendChild/setProperty/setAttribute. Getter methods returns values which have been set from the server side only.

Note
The created Element is virtually mapped to be connected to the ShadowRoot of the PolymerTemplate even if it would be deeper in the shadow tree. The virtually mapped components can not be removed from the DOM by removing them on the server side.
Note
The declared type used in an @Id injection declaration must have a default constructor to be able to instantiate it.
Tip
The @Id annotation can also be used to inject an Element instance instead of a Component instance in case you want to use low level API or there is no appropriate HTML component available.
Note
You can detect whether a component is part of a Template by using the isTemplateMapped method. See the Integrating components in a PolymerTemplate tutorial for more details.