I'm a Tapestry5 user and I have a form with a gazillion fields on it that all increment with a numeric.

example

timesheet.tsHours01 timesheet.tsHours02 etc

I'd like to dynamically loop this, but have failed to fully get it working. What I've tried thus far.

@Property
private List<TimeSheetEntity> timeSheetEntity;

@Property
private List<TsWhour> tsWhours;

@Property
private TsWhour tsWhour;

public void onPrepareFromForm() {
    this.timeSheetEntity = timeSheetService.getCreateOrUpdate(timeSheetEntity);

    tsWhours = new ArrayList<TsWhour>();
    tsWhours.add(new TsWhour(timeSheetEntity, "TsWhours01"));
    tsWhours.add(new TsWhour(timeSheetEntity, "TsWhours02"));
    tsWhours.add(new TsWhour(timeSheetEntity, "TsWhours03"));
}

public class TsWhour {

    private TimeSheetEntity timeSheetEntity;
    private String id;

    private BigDecimal property;

    public TsWhour() {
    }

    public TsWhour(TimeSheetEntity timeSheetEntity, String id) {
        this.timeSheetEntity = timeSheetEntity;
        this.id = id;
    }

    public BigDecimal getProperty() {
        try {
            Method method = TimeSheetEntity.class.getMethod("get" + id);                 
            return (BigDecimal) method.invoke(timeSheetEntity);
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(TimeSheet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(TimeSheet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(TimeSheet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(TimeSheet.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(TimeSheet.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;           
    }

    public void setProperty(BigDecimal value) {
        System.out.println(value);
    }

    public TimeSheetEntity getTimeSheetEntity() {
        return timeSheetEntity;
    }

    public void setTimeSheetEntity(TimeSheetEntity timeSheetEntity) {
        this.timeSheetEntity = timeSheetEntity;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

I'm able to get the page to load, but when I save it fails. If possible, I would rather not specify the datatype as a bigdecimal to keep it completely dynamic.

有帮助吗?

解决方案

Well, first off, you can use the PropertyAccess service as a much easier way to get at your dynamically computed property.

What is setting and changing the id? Is TsWhour a component?

Basically, at form submission time, Tapestry will need to retrace its steps to each component and each change of that id property. The Loop component, inside a Form, knows how to do this (though you can configure it to optimize things a bit).

You haven't provided nearly enough context.

Finally, perhaps there's an issue with your data modelling if you have a "gazillion" virtually identical fields. Maybe what you need looks more like a Map than an Object. Maybe you need a simple way to extract data from your entity type (I'm assuming you are using Hibernate or JPA) into an intermediate type that is easier to work with in the UI layer.

其他提示

If, as Howard suggested, you want to use a java.util.Map as an intermediate object you can use the map: binding prefix from tapestry-stitch. Demo here

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top