Skip to content

Commit

Permalink
Tutorial for using beans in a template model (#933)
Browse files Browse the repository at this point in the history
Fixes #881
  • Loading branch information
Artur- committed Jun 8, 2016
1 parent afdc4a4 commit 2649d87
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 0 deletions.
1 change: 1 addition & 0 deletions hummingbird-documentation/Overview.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ These tutorials show how the different features are used.
* Template API
** <<tutorial-template-basic#,Creating A Simple Component Using the Template API>>
** <<tutorial-template-bindings#,Binding Model Data in a Template>>
** <<tutorial-template-model-bean#,Using Beans with a Template Model>>
** <<tutorial-template-class-name-binding#,Binding Class Names in a Template>>
** <<tutorial-template-components#,Adding Components to a Template>>
** <<tutorial-template-include#,Including Templates in Templates>>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.humminbird.tutorial.template;

import com.vaadin.annotations.EventHandler;
import com.vaadin.humminbird.tutorial.annotations.CodeFor;
import com.vaadin.hummingbird.template.model.TemplateModel;
import com.vaadin.ui.Template;

@CodeFor("tutorial-template-model-bean.asciidoc")
public class BeanInTemplateModel {
public class Person {
private String firstName, lastName;
private int age;

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 void setLastName(String lastName) {
this.lastName = lastName;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

public interface FormModel extends TemplateModel {
public void setPerson(Person person);

public Person getPerson();
}

public class Form extends Template {
public Form() {
Person person = new Person("John", "Doe", 82);
getModel().setPerson(person);
}

@Override
protected FormModel getModel() {
return (FormModel) super.getModel();
}

@EventHandler
public void setNameToJeff() {
getModel().getPerson().setFirstName("Jeff");
}
}

}
121 changes: 121 additions & 0 deletions hummingbird-documentation/tutorial-template-model-bean.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
ifdef::env-github[:outfilesuffix: .asciidoc]
= Using Beans with a Template Model

For an introduction to templates and template models, see <<tutorial-template-basic#,Creating A Simple Component Using the Template API>>

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:

[source,html]
----
<div>
<div>
<span>First name</span>
<input [value]="person.firstName" />
</div>
<div>
<span>Last name</span>
<input [value]="person.lastName" />
</div>
<div>
<span>Email</span>
<input [value]="person.email" />
</div>
</div>
----

Assuming your Person bean looks like:

[source,java]
----
public class Person {
private String firstName, lastName;
private int age;
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 void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
----

You can specify your model to use a Person bean by adding a setter and a getter for it:

[source,java]
----
public interface FormModel extends TemplateModel {
public void setPerson(Person person);
public Person getPerson();
}
----

In the template you can initialize the model by setting a new person instance to it:

[source,java]
----
public class Form extends Template {
public Form() {
Person person = new Person("John", "Doe", 82);
getModel().setPerson(person);
}
@Override
protected FormModel getModel() {
return (FormModel) super.getModel();
}
}
----

[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()` 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:

[source,java]
----
public class Form extends Template {
@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.

0 comments on commit 2649d87

Please sign in to comment.