Using Beans with a PolymerTemplate Model
For an introduction to templates see Creating A Simple Component Using the Template API and template models see Binding Model Data in a PolymerTemplate.
Using beans in models provides you with an easy way of defining your model or reusing existing beans for the model. You can use any bean together with the model as long as it has a public no-arg constructor.
A typical use case would be a form where you want to edit the contents of one or more entities. The template for a form for editing a Person
bean might for instance look like:
MyForm html template
<dom-module id="my-form">
<template>
<div>
<div>
<span>First name</span>
<input value="[[person.firstName]]" />
</div>
<div>
<span>Last name</span>
<input value="[[person.lastName]]" />
</div>
<div>
<span>Age</span>
<input value="[[person.age]]" />
</div>
</div>
<div>
<button on-click="setNameToJeff">Set Name To Jeff</button>
</div>
</template>
<script>
class MyForm extends Polymer.Element {
static get is() {
return 'my-form'
}
}
customElements.define(MyForm.is, MyForm);
</script>
</dom-module>
If you have a Person bean that looks like:
Person bean
public class Person {
private String firstName, lastName;
private int age;
private Long id;
public Person() {
// Needed for TemplateModel
}
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public Long getId() {
return id;
}
}
You can specify your model to use a Person bean by adding a setter and a getter for it:
FormModel model definition as an interface
public interface FormModel extends TemplateModel {
@Exclude("id")
void setPerson(Person person);
Person getPerson();
}
Tip | You can use the @Include annotation and provide a list of properties that you want import (all other properties will be excluded) or @Exclude for a list you want to exclude. In this specific case the @Include({“firstName”,”lastName”,”age”}) would be the same as the shown @Exclude(“id”) annotation. |
Tip | You can include and exclude sub bean properties by using the dot-annotation, e.g. @Exclude(“account.password”) . |
Note | You don’t have to declare the Person type as a class. It may be declared as an interface. And there is no need to create its instance and use setter. You just may call getPerson() and the model will return for you an empty proxy object which you can use to set its property directly. |
Note | When setting backend data directly to the model, you must exclude any bean properties that would lead to circular dependencies. For instance, if a Patient bean would have a property Doctor doctor , the Doctor bean must not have a property of type Patient (or as a generic type for a collection property), as that would lead to a circular dependency. |
In the template you can initialize the model by setting a new person instance to it:
Form template class
public class Form extends PolymerTemplate<FormModel> {
public Form() {
Person person = new Person("John", "Doe", 82);
getModel().setPerson(person);
}
}
Note | If you later on update the Person person bean created in the constructor, nothing will happen to the model. The bean values are copied by setPerson and the bean is not attached to the model in any way. |
To update the values in the model, you can use getModel().getPerson()
or getModel().getProxy("person", Person.class)
to get a proxy Person
object, which is attached to the model. Any changes you do to that proxy object will automatically update the model:
Form template with an eventHandler for nameChange
public class Form extends PolymerTemplate<FormModel> {
@EventHandler
public void setNameToJeff() {
getModel().getPerson().setFirstName("Jeff");
}
}
Note | Your bean will never be stored as a bean in the model, instead the individual parts of the bean will be stored. No method will ever return the original bean to you. |
Note | The proxy bean returned by the getter is not meant to be passed on to an EntityManager or similar. It is purely meant for updating the values in the model. |
Warning | There is at the time of writing no way to get a detached bean from the model. |
When wanting to use model data with an entity manager you need to re-instantiate a new entity and set the values using the getters for the item gotten from the model.
Note! in the example that we can’t send the Person object from the model directly to the service as the the object is proxied and only returns data when the getters are used.
Java
public class OrderForm extends PolymerTemplate<FormModel> {
public interface FormModel extends TemplateModel {
@Exclude("id")
void setPerson(Person person);
Person getPerson();
}
public OrderForm() {
Person person = new Person("John", "Doe", 82);
getModel().setPerson(person);
}
@EventHandler
public void submit() {
Person person = getModel().getPerson();
getService().placeOrder(new Person(person.getFirstName(), person.getLastName(), person.getAge()));
}
private OrderService getService() {
// Implementation omitted
return new OrderService();
}
}