You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Geoff Callender <ge...@gmail.com> on 2007/12/08 10:24:58 UTC

Re: T5: Edit page best practice?

Hi,

Here's my new attempt at incorporating T5 best practice from this  
thread into my EditPerson page.  I'm looking for suggestions on how to  
improve it further.

	private Long _personId;
	
	@Persist("client")
	// Persistence is needed here because this is a detached Entity  
Bean.  When we call the service to
	// accept our changes, it will need its id and version fields intact  
to be able to do optimistic
	// locking check and a successful merge. "client" is used so that  
even if you use the Back button
	// to get to this page, we will have the right Person object.
	private Person _person;
	
	@Persist("client")
	private boolean _needsRefresh = true;

	void onActivate(Long id) throws Exception { _personId = id; }

	Long onPassivate() { return _person.getId(); }

	void setupRender() throws Exception {
		if (_needsRefresh) {
			_person = getPersonService().findPerson(_personId);
		}
		_needsRefresh = true;
	}

	void onValidate() throws Exception {
		_needsRefresh = false;
		if (...a bit of validation logic detects an error...) {
			_form.recordError(...);
		}
	}
	
	Object onSuccess() {
		try {
			getPersonService().changePerson(_person);
			_nextPage.onActivate(_personId);
			_needsRefresh = true;
			return _nextPage;
		}
		catch (Exception e) {
			_form.recordError(ExceptionUtil.getRootCause(e));
			return null;
		}
	}

	void cleanupRender() {
		   _form.clearErrors();
	}
	
Some notes and questions:

1. Detached object - Person is a detached object.  I am avoiding  
refreshing it every time in setupRender() because a) it would  
overwrite the user's changes, and b) it would defeat optimistic  
locking: if someone else has changed the object then I do want  
getPersonService().changePerson(_person) to reject the transaction  
when Save is pressed.

2. _needsRefresh - it's just a method of preventing the refresh when  
we re-display due to error.  This seems clumsy.  Suggestions?

3. Thread-safety - I'm using "client" persistence to avoid the whole  
thread-safety issue caused by the user opening a new window or tabs in  
same browser (T5 can't tell them apart so they share the same  
HttpSession).

Comments please!

Thanks,

Geoff


On 26/11/2007, at 10:27 PM, Geoff Callender wrote:

> Hi,
>
> I'm looking for suggestions on how to improve this EditPerson page  
> to T5 best practice.
>
> 	private Long _personId;
>
> 	@Persist
> 	private Person _person;
>
> 	public void onActivate(Long id) { _personId = id; }
>
> 	public Long onPassivate() { return _personId; }
> 	
> 	void onPrepareFromForm() {
> 		if (_person == null || _person.getId().equals(_personId)) {
> 			_person = getSecurityFinderService().findPerson(_personId);
> 		}
> 	}
>
> 	Object onSuccess() {
> 		if (...a bit of validation logic detects an error...) {
> 			_form.recordError(...);
> 			return null;
> 		}
> 		etc...
> 		_person = null;
> 		return _nextPage;
> 	}
>
> 	Object onActionFromCancel() {
> 		_person = null;
> 		return _previousPage;
> 	}
>
> 	void cleanupRender() {
> 		_form.clearErrors();
> 	}
>
> Some notes and questions:
>
> 1. Persist - Is there an alternative?  It's used here to keep  
> _person populated in case onSuccess() detects an error and  
> redisplays the page.
>
> 2. Housekeeping - I'm nullifying _person in each method that returns  
> a different page.  This seems clumsy.  Suggestions?
>
> 3. Thread-safety - is there a thread-safety issue if the user has  
> opened a new window in same browser - can T5 tell them apart or do  
> they share the same HttpSession?
>
> 4. onPrepareFromForm() - this looks a bit clumsy to me.  If the user  
> hits Reload, or if the user hits the Back button then "pagelinks"  
> back in, onPrepareFromForm() wlll not call findPerson(...).  The  
> _person isn't refreshed at all!  Thoughts?
>
> Thanks,
>
> Geoff