Thank you for all these replies. I've already committed the lazy loading editingContext() method for the components that need it!
Ricardo: Thank you for your solutions there... reading that has made me realise I'm not making use of bindings properly but instead using public setters and getters on components. Will take a little longer to fix! Will digest the rest! Thank you Mark 2009/3/24 Ricardo J. Parada <[email protected]>: > > On Mar 24, 2009, at 8:44 AM, Mark Wardle wrote: > >> When is the appropriate time to create an editingcontext - within a >> component's constructor? > > I do the same thing that Kieran suggested. My component has an > editingContext() method which creates its own editing context. > >> If so, is it appropriate to pass a handle to >> the editingcontext between components? For example, I have a UserEdit >> component, that takes a User as a binding, and allows a user to edit >> that user's details (subject to permissions). > > You could do that as long as it's okay to mess with that editing context. > But you could run into trouble, for example if you start editing your User > object and then go somewhere else in the application, modify something and > save then if the editing context is the same as the one used for these > components then you may be saving the pending edits to the User object as a > side effect and not exactly what the user would expect. > > Soo... what I do is, if your UserEdit component is being handed the User > object then it can simply get a copy of of the user object into the > UserEdit's local editing context. I do this in a couple of different ways. > Here's the one with less code: > > /** Returns copy of user object in the UserEdit's local editing context */ > > public User user() { > User user = (User) valueForBinding("user"); > return user.localInstanceIn(editingContext()); > } > > But you could have trouble here when they start editing the user object and > then in a subsequent request you are handed in a different user object. All > of a sudden you will start editing a different user object and you still > have pending edits for the other user object. > > So what I do is usually the version that involves a bit more code. I you > are using project Wonder and your component inherits from ERXComponent then > I usually do this in preAppendToResponse as follows : > > public preAppendToResponse(WOResponse response, WOContext context) { > // See what user object we're being handed in > User aUser = (User) valueForBinding("user"); > > // Convert it to our local editing context > aUser.localInstanceIn(editingContext()); > > // If the user handed in is a different user from the one we're > currently editing... > > if (user != aUser) ) { > // ... then throw away any pending edits ... > editingContext().revert(); > > // ... and start using that user object > user = aUser; > } > } > > public User user() { > return user; > } > > > Now in the real world sometimes I get handed in a brand new object which was > created in an external editing context and which is okay to mess with. For > example let's say the parent component is the one that hands in the user > object to the UserEdit component, and let's say that it was created like > this prior to be handed in to UserEdit: > > EOEditingContext newEditingContext = ERXEC.newEditingContext(); > User aUser = new User(); > newEditingContext.insertObject(aUser); > aUser.setFoo("foo"); > > Then your user edit is handed in this user object. In this case I assume > that I can use that editing context and can have the following bit of code > in preAppendToResponse(): > > // See what user object we're being handed in > User aUser = (User) valueForBinding("user"); > > // See if it's a new object and not exactly the one we're currently > editing > if (aUser.isNewObject() && aUser != user) { > // use the externally created editing context as the local > editing context > _editingContext = aUser.editingContext(); > user = aUser; > } > > > Ok... so that's close to what I do normally. Not sure if it's the best way, > but it seems to work for me. > > >> >> What if I then have subcomponents that need to use the parent editing >> context? Is it appropriate to get the parent's editingcontext from the >> EO itself? >> > > I document this for the component. For example, in your UserEdit component > documentation I would mention that it uses its own editing context for > editing unless the user object handed in is a new object that has not been > saved to the database yet. > >> Once I start thinking about that, it looks like I'm writing lots of >> code which is fairly repetitive and thought that there must be a >> better way? Am I missing something obvious? I don't want to make >> things highly modal, and I usually don't wish to preserve state >> between components unless the user specifically requests it. > > Yes I've thought about abstracting that code so I don't repeat it. The user > i-var and binding could be called document. > And have that code in a superclass in preAppendToResponse(). Then the > UserEdit component would extend that component. If your subclass has some > code in preAppendToResponse then you would have to call > super.preAppendToResponse() to make sure that logic is not skipped. > > > > ______________________________________________________________________ > This email has been scanned by the MessageLabs Email Security System. > For more information please visit > http://www.messagelabs.com/email______________________________________________________________________ > -- Dr. Mark Wardle Specialist registrar, Neurology Cardiff, UK _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list ([email protected]) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to [email protected]
