List editing with Editor/RequestFactory + GAE/Objectify

172 views
Skip to first unread message

Tobias

unread,
Nov 1, 2010, 10:14:19 AM11/1/10
to Google Web Toolkit
Hi,

to get accustomed to GAE as well as GWT 2.1, I am working on a pet
project for managing Recipes. A Recipe has multiple Ingredients, which
I want to display in a CellTable, each Ingredient having (editable)
columns for Amount and Type. New Ingredient lines in the table can be
added with a button, existing ingredients can be removed and reordered
by buttons (or DnD later).
So now I am trying to figure out how to wire this up with the Editor
framework and RequestFactory on the Client-side and the GAE datastore
and Objectify (or JDO, if that makes it any easier). I created some
dummy Recipe object with a getIngredients()-list with some dummy
Ingredients and managed to get the CellTable populated with these by
the Editor driver automatically.

What I do not understand however is how far this databinding goes? How
would I implement an "Add Ingredient" button, that would create a new
empty Ingredient, and would I have to create the CellTable row for
that manually or would the Editor driver do that for me?

My other question is related to the Server model. RequestFactory seems
to be tailored to JDO/JPA. Apparently, to enable the Editor framework
work, my Recipe class needs a getIngredients() method. How should I
implement this in an Objectify based persistence?

Thank you,
Tobias

David Chandler

unread,
Nov 1, 2010, 12:26:18 PM11/1/10
to google-we...@googlegroups.com
Hi Tobias,

The RequestFactory sample apps in GWT 2.1 use JDO and JPA because
these are the Java persistence APIs offered by App Engine; however,
RequestFactory has no dependency on them, and you can use Objectify
instead. RequestFactory won't be able to serialize the Objectify Key
object so you should expose only convenience methods like getParent()
below that know how to map the key to the actual entity. Here's an
example that exposes only RequestFactory-safe methods:

@ProxyFor(ListItem.class)
public interface ListItemProxy extends EntityProxy
{
Long getId();
String getItemText();
void setItemText(String itemText);
void setParent(ItemListProxy editList);
ItemListProxy getParent();
}

@Entity
public class ListItem
{
@Id private Long id;
private String itemText;
@Version
private Integer version;
// Dummy field due to JsonRequestProcessor:1543
transient private ItemList parent;
// Real parent key used by Objectify
@Parent private Key<ItemList> parentKey;

public ListItem()
{
// No-arg constructor required
}

public void setParent(ItemList parent)
{
this.parentKey = new ItemListDao().key(parent);
}

public ItemList getParent()
{
try
{
return new ItemListDao().get(parentKey);
}
catch (EntityNotFoundException e)
{
e.printStackTrace();
}
return null;
}
}

HTH,
/dmc

> --
> You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
> To post to this group, send email to google-we...@googlegroups.com.
> To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
>

--
David Chandler
Developer Programs Engineer, Google Web Toolkit
http://googlewebtoolkit.blogspot.com/

Tobias

unread,
Nov 1, 2010, 1:42:13 PM11/1/10
to Google Web Toolkit
Thanks David,

I now used the same pattern for retrieving the collection and
implemented my getIngredients() method in a similar way. However I am
still stuck on how to add an element to the list, so that the Editor
framework notices it and appends a table row. On my page I basically
have a CellTable that's wrapped with a HasDataEditor, and an "Add
elem" button, which is supposed to add new (blank) entries to the
CellTable.
I found that the HasDataEditor uses a ListEditorWrapper. This
wrapper's purpose seems to synchronize the data list with the editor
display, in my case the CellTable. But how to I add elements to the
data list?
I tried using the RequestFactory to add ingredients on the server, but
this does not trigger any refresh on the Editor, the new ingredients
do not show up until the next page refresh. Ok, that's kinda obvious
since the RequestFactory can't know that this changed the Recipe and
therefore the RecipeProxy needs an update.
So my next try was to get a new valid IngredientProxy object as a
response from appending a new Ingredient in the server and adding it
to the RecipeProxy like this

recipeProxy.getIngredients().add(addedIngredient);

No exceptions, but also there does not seem to be any magic that would
cause a refresh of the editors in this case either.
I finally had some success by using the RequestContext to create a new
ingredient on the server and directly adding the returned proxy to the
observed ListEditorWrapper like this:
requests.recipeRequest().addIngredient().using(recipe)
.fire(new Receiver<IngredientProxy>() {

@Override
public void onSuccess(IngredientProxy response) {
view.ingredientsEditor().getList().add(response);
}
});

I doubt that this is the way to go, since it introduces some tight
coupling and also, I cannot edit list entries that I created this way,
it gets me a "java.lang.IllegalStateException: The AutoBean has been
frozen". I guess I must make the new proxy somehow part of the Request
that the Driver works on?

I guess I am not really getting how the Editor-framework works. I've
worked with a couple of databinding solutions before, mostly JFace,
but I am stuck on this one. I find it particularly hard to figure
things out because of the rebinding that's going on.

Thanks in advance,
Tobias
> > For more options, visit this group athttp://groups.google.com/group/google-web-toolkit?hl=en.
Reply all
Reply to author
Forward
0 new messages