Hi,
I have a Dialog that lets the user modify an OrderedCollection (inside a ListModel). It doesn't work as expected, since Dialog uses an AspectBuffer which in turn does a #copy of it's subject. So, any changes made to the list with the dialog are visible on the model, even if the user clicks on the Cancel button. I decided to create a subclass of Dialog called DeepCopyDialog that uses a subclass of AspectBuffer, called DeepCopyAspectBuffer. Everything OK, so far. However, all the dialogs in this project (the Formula One thing from The Dolphin Smalltalk Companion) descend from a F1Dialog that has some common methods. If I make F1Dialog a subclass of DeepCopyDialog, all of my dialogs will become DeepCopy ones, and I don't wat that. Only one should be a DeepCopyDialog and a F1Dialog. All others should be only F1Dialogs. What's the best way to solve this sort situation without resorting to multiple inheritance? Thanks |
> What's the best way to solve this sort situation without resorting to
> multiple inheritance? I don't know if I understood your problem correctly, but I think you wont need multiple inheritance, or even to create the class DeepCopyDialog at all. I think all it takes is to redefine the method #bufferedModelFor: in the dialog which manipulates the collection to use a different wrapper on your model (in your case, one that makes a deep copy of it, and sets its contents properly when applied). The comment for #bufferedModelFor: says that: "[...] May be overriden by subclasses that wish to use a different buffering scheme." Regards Martin |
On Mon, 28 Mar 2005 11:26:35 -0300, "Martin" <[hidden email]>
wrote: >I think all it takes is to redefine the method #bufferedModelFor: in the >dialog which manipulates the collection to use a different wrapper on your >model (in your case, one that makes a deep copy of it, and sets its contents >properly when applied). The comment for #bufferedModelFor: says that: > >"[...] May be overriden by subclasses that wish to use a different buffering >scheme." Thanks, you are right. However, it still doesn't work. :-( Let's recapitulate: I created a subclass of AspectBuffer called DeepCopyAspectBuffer and it overrides one method: #subject subject: aSubjectModel "Does a deepCopy instead" subject := aSubjectModel. subjectCopy := aSubjectModel deepCopy. "the only difference" aspects := IdentityDictionary new. I also have a model subclass called Season that has a ListModel aspect that is shared with the presenter (called SeasonPresenter). This ListModel is accessed via the #scoreDefinition method. I'm setting the model of the ListPresenter in SeasonPresenter like this: SeasonPresenter>>model: aSeason super model: aSeason. "The shared ListModel:" scoreListPresenter model: (self model scoreDefinition). I also override the #bufferedModelFor: method as you suggested: bufferedModelFor: aSubjectModel "Private - Answers a deepCopied buffer, since self presents a list (shallow copy isn't enough)" ^DeepCopyAspectBuffer subject: aSubjectModel. If I show a Season on a DialogSeason and add a few entries to the list and then click on the OK button, the list in Season remains unchanged. =:-O The culprit seems to be AspectBuffer>>apply which does nothing in this particular case. I think I should override it in DeepCopyAspectBuffer, but I'm not sure what I should do in that method. Or perhaps the problem is my SeasonPresenter>>model: Besides, I'm not sure if I really understand what's going on... Any suggestions? O:-) Is the whole idea of creating DeepCopyAspectBuffer a good idea? Thanks |
Fernando wrote:
> The culprit seems to be AspectBuffer>>apply which does nothing in this > particular case. > > I think I should override it in DeepCopyAspectBuffer, but I'm not sure > what I should do in that method. Or perhaps the problem is my > SeasonPresenter>>model: > > Besides, I'm not sure if I really understand what's going on... > > Any suggestions? O:-) Is the whole idea of creating > DeepCopyAspectBuffer a good idea? You are probably missing a #aspectValue: send for your list. A simpler way to do this without subclassing is to override #copy to make a copy of your list. eg. copy | answer | answer := super copy. answer someList: someList copy. "And I think you don't want a deep copy here." ^answer model: aModel super model: aModel. ... self model aspectValue: #someList. ... This doesn't always work of course, depending on your own usage pattern of #copy and how you want the list to be synchronised etc. |
On 28 Mar 2005 19:56:45 -0800, "[hidden email]"
<[hidden email]> wrote: > >You are probably missing a #aspectValue: send for your list. A simpler You mean it's necessary to create an AspectValue even when sharing a ListModel between the Model and the Presenter? |
Browse the AspectBuffer class which is the buffer being used by Dialog.
If you look in #apply, you will notice that the buffer copies the aspects/properties specified in the ivar aspects. Sending #aspectValue: for the list is just a way (I know some other people does it this way too. I'm not sure if this is the right way since it is just using the side-effect but it works :)) for us to update the aspects ivar to include the list. |
Free forum by Nabble | Edit this page |