Docs

Documentation versions (currently viewingVaadin 14)

You are viewing documentation for an older Vaadin version. View latest documentation

Using Beans with a Polymer Template Model

Note
Use Lit templates instead
Lit templates are recommended. Polymer templates are available in the next long term supported Vaadin version (LTS), but they are deprecated.

Using beans is an easy way to define a model or to reuse existing beans in a model. You can use any bean together with your model, provided it has a public no-argument constructor. See Binding Model Data in a PolymerTemplate for more.

A typical use case for using beans in a model is a form that allows the user to edit the content of one or more entities.

Example: JavaScript Polymer template defining a form to edit the Person bean (see below).

class MyForm extends PolymerElement {
    static get template() {
        return html`
            <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>`;
    }

    static get is() {
        return 'my-form'
    }
}

customElements.define(MyForm.is, MyForm);

Example: Java class defining a 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;
    }
}

Example: Java interface defining a setter and getter for the Person bean.

public interface FormModel extends TemplateModel {
  @Exclude("id")
  void setPerson(Person person);
  Person getPerson();
}
  • The @Exclude annotation allows you to provide a list of properties you want to exclude. As an alternative, you can use the @Include annotation and provide a list of properties that you want import (all other properties are excluded). In this example, @Include({"firstName","lastName","age"}) is the same as @Exclude("id").

  • The Person type can be declared as an interface (you do not need to declare it as a class): it is not necessary to create its instance and use a setter, uou can simply call getPerson() and the model will return an empty proxy object that you can use to set its property directly.

Tip
You can include and exclude sub-bean properties using the dot annotation, for example, @Exclude("account.password").
Note
When setting back-end data directly to the model, you should exclude any bean properties that could lead to circular dependencies. For example, if a Patient bean has the Doctor doctor property, the Doctor bean should not have a property of the type Patient (or a generic type for a collection property), as this leads to a circular dependency.

Initializing the Model

You can initialize the model by setting a new person instance to it in the Java template class.

Example: Polymer Java template class.

public class Form extends PolymerTemplate<FormModel> {
    public Form() {
        Person person = new Person("John", "Doe", 82);
        getModel().setPerson(person);
    }
}
  • If you later on update the Person person bean created in the constructor, the model remains unaffected. The bean values are copied only when the setPerson method is called. Thus, the bean is not attached to the model in any way.

Updating the Model

To update the values in the model, you can use the getModel().getPerson() or getModel().getProxy("person", Person.class) methods to get a proxy Person object that is attached to the model. Any changes to the proxy object automatically update the model.

Example: Using the @EventHandler annotation to update the model.

public class Form extends PolymerTemplate<FormModel> {
    @EventHandler
    public void setNameToJeff() {
        getModel().getPerson().setFirstName("Jeff");
    }
}
  • The individual parts of the bean are stored in the model, not the bean itself. No method that can return the original bean exists.

  • The proxy bean returned by the getter is not meant to be passed on to an EntityManager or similar. Its only purpose is to update the values of the model.

Warning
There is currently no way to get a detached bean from the model.

Using Model Data with an Entity Manager

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 received from the model.

Note
In the previous example, we cannot send the Person object from the model directly to the service, as the object is proxied and only returns data when the getters are used.

Example: Using an entity manager to update the model data.

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

FFB658DF-2399-4494-8441-5B0253260DCC