I agree with Thiago: "My best practices for persisting fields is this: just do it when there's no way of avoiding it."
Most JumpStart examples avoid @Persist. The reasons are given in the "Caution" section of this page: http://jumpstart.doublenegative.com.au/jumpstart7/examples/state/storingdatainapage In T5.3, you need persistence to avoid losing certain fields, eg. hidden fields, when a Form is in error. That's because it redirects and the ValidationTracker only looks after the input-capable fields. You'll see JumpStart for T5.3handling it with flash persistence. T5.4 is much simpler: you no longer need persistence because it doesn't redirect (on Form error). As for AjaxFormLoop, which I don't like either, here are three examples that do not use @Persist. Like Lance's suggestion, they use an encoder: http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/formloop1 http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/formloopwithholders1 http://jumpstart.doublenegative.com.au/jumpstart/examples/ajax/formlooptailored1 Geoff On 15 Aug 2014, at 8:16 pm, Lance Java <lance.j...@googlemail.com> wrote: > Thinking about this a bit more, you can probably avoid @Persist by using an > appropriate ValueEncoder. > > eg: > <t:ajaxformloop t:id="foos" source="foos" value="foo" > encoder="lazyEncoder">...</t:ajaxformloop> > > public class LazyValueEncoder<T> implements ValueEncoder<T> { > private static final String CLIENT_NULL = "XXX"; > private ValueEncoder<T> encoder; > private Class<T> type; > public LazyValueEncoder<T>(ValueEncoderSource source, Class<T> type) { > this.encoder = source.getValueEncoder(type); > this.type = type; > } > public String toClient(T value) { > if (value == null) { > return CLIENT_NULL; > } > return encoder.toClient(value); > } > public T toValue(String client) { > if (CLIENT_NULL.equals(client)) { > return type.newInstance(); > } > return encoder.toValue(client); > } > } > > public class MyPage { > @Property private List<Foo> foos; > @Property private Foo foo; > @Inject private ValueEncoderSource source; > > public ValueEncoder<Foo> getLazyEncoder() { > return new LazyValueEncoder(source, Foo.class); > } > > public Foo onAddRowFromFoos() { > return null; > } > } > > Warning: Untested code