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.
HTML
<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.
Java
@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:
Java
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. |