I am trying to do MVP right this time. ;) I am trying to let go of all my
previous dialog based development experience and let the spirit of MVP guide me into UI bliss. Should keyedValue: be implemented in AspectBuffer? I am developing a dialog whose model is something like a database record. The fields are like a dictionary. I have created a presenter for each field, and I believe I want to use keyedValue: to get a ValueKeyedAdaptor. When I use this method on the Dictionary it works fine except that changes are not buffered, they are applied directly. I think I need to send this message to model which is an AspectBuffer so that the changes will be buffered. Should this method be implemented there? Am I on the right track? If not can someone help me onto the right track? ;) Thanks, Chris |
"Christopher J. Demers" <[hidden email]> wrote in
message news:95po6c$iaqv7$[hidden email]... > Should keyedValue: be implemented in AspectBuffer? I am developing a dialog > whose model is something like a database record. The fields are like a > dictionary. I have created a presenter for each field, and I believe I want > to use keyedValue: to get a ValueKeyedAdaptor. When I use this method on > the Dictionary it works fine except that changes are not buffered, they are > applied directly. I think I need to send this message to model which is an > AspectBuffer so that the changes will be buffered. Should this method be > implemented there? Am I on the right track? If not can someone help me > onto the right track? ;) The approach I take is to have a model which answers up to #at: and #at:put: to supply and set its attributes. Then, in #model: for the presenter, I do something like the following. (My model has a record which knows its field names). ----------------------------------- model: aModel "Setup the submodels for each of the subpresenters. The ValueKeyedAdaptor for, e.g., an 'address' field causes the message at: 'address' or at: 'address' put: <somevalue> to be sent to the BusinessObject which is the presenter's model. What happens if aModel is a ValueKeyedAdaptor for a subform? Try taking its _value_ when calling #model:. Only set up submodels where the presenter's name matches a field of the form's business object. " | fieldNames fieldPresenters | super model: aModel value. fieldNames := aModel record fieldNames. fieldPresenters := subPresenters select: [:each | fieldNames includes: (self nameOf: each) ]. fieldPresenters do: [ :each | each model: (ValueKeyedAdaptor subject: self model value key: (self nameOf: each)) ]. ----------------------------------- I hope this helps. -- Frank [hidden email] |
Thanks for the suggestion. However changes are still not buffered with this
way. As I understand it, with AspectBuffers changes are made to a copy of the actual model. If the OK button on a Dialog is selected the changes are applied via the aspects collection. If the Cancel button is selected the changes are not applied. This seems to work with ValueAspectAdaptors but there does not seem to be a provision for ValueKeyedAdaptors to work in this way with AspectBuffers. I think I am going to try adding DNU support to my record class, so I can use the existing aspectValue: message. Thanks for the info, Chris Frank Sergeant <[hidden email]> wrote in message news:GR_f6.728$[hidden email]... > > The approach I take is to have a model which answers up to #at: and #at:put: > to supply and set its attributes. Then, in #model: for the presenter, I do > something like the following. (My model has a record which knows its field > names). > > ----------------------------------- > > model: aModel > "Setup the submodels for each of the subpresenters. The ValueKeyedAdaptor > for, e.g., an 'address' field causes the message at: 'address' or at: > 'address' put: <somevalue> to be sent to the BusinessObject which is the > presenter's model. What happens if aModel is a ValueKeyedAdaptor for a > subform? Try taking its _value_ when calling #model:. Only set up > where the presenter's name matches a field of the form's business object. " > > | fieldNames fieldPresenters | > > super model: aModel value. > > fieldNames := aModel record fieldNames. > > fieldPresenters := subPresenters select: [:each | fieldNames includes: (self > nameOf: each) ]. > > fieldPresenters do: > > [ :each | each model: (ValueKeyedAdaptor > > subject: self model value > > key: (self nameOf: each)) ]. > > ----------------------------------- > > I hope this helps. > > -- Frank > > [hidden email] > > |
"Christopher J. Demers" <[hidden email]> wrote in
message news:95q1iq$i5rlh$[hidden email]... > Thanks for the suggestion. However changes are still not buffered with this > way. As I understand it, with AspectBuffers changes are made to a copy of > the actual model. If the OK button on a Dialog is selected the changes are > applied via the aspects collection. If the Cancel button is selected the > changes are not applied. This seems to work with ValueAspectAdaptors but > there does not seem to be a provision for ValueKeyedAdaptors to work in this > way with AspectBuffers. Oops, I left some information out from my previous post. (And, may well still be leaving something out.) > I think I am going to try adding DNU support to my record class, so I can > use the existing aspectValue: message. That shouldn't be necessary. Following is an example #model: from one of my subclasses of Dialog. The superclass (Dialog) takes care of creating the buffered model. For this to work, I added two methods to AspectBuffer (#keyedApply and #keyedAspectValue: ) then override #apply in the Dialog subclass to have it send #keyedApply to the model instead of #apply. ------------------------ model: aSubjectModel "Set the model of the receiver to be a buffer onto of aSubjectModel." | aspectBuffer | super model: aSubjectModel. " ** now wire up the sub models automatically ** " aspectBuffer := self model. subPresenters do: [:each | aspectBuffer value at: (self nameOf: each) asSymbol ifPresent: [:what | each model: (aspectBuffer keyedAspectValue: (self nameOf: each) asSymbol)]]. ------------------------ AspectBuffer>>keyedApply "Apply the aspects held by the receiver in the model copy back to the original model" aspects do: [:each | self subject perform: each putSelector with: each key with: each value ] ------------------------ AspectBuffer>>keyedAspectValue: aKey "Answer a ValueAspectAdapter for anAspectSymbol of our copied model. If a request for this aspect has already been registered then the same adapter model is answered. Otherwise a new one is created and registered in our aspects dictionary. This is the same as #aspectValue: except that the aspect symbol is a key rather than an attribute." ^aspects at: aKey ifAbsentPut: [ ValueKeyedAdaptor subject: subjectCopy "aspect:" key: aKey] ------------------------ -- Frank [hidden email] |
Thanks, this is exactly what I was after. I thought I might have to do
something like this. I just wanted to make sure I was working the way MVP wants me to work. I wonder if OA might consider adding something like this to the base system? It looks like Dolphin has the beginnings of what we need but stops just short of the full implementation (at least for Dialogs). I have followed your example and it works, thank you! I am thinking of a slight variation on your approach: I could create a method called applyTo: in ValueKeyedAdaptor and ValueAspectAdaptor, that would do "its perform thing". Then I would edit AspectBuffer<<apply so that it just sends applyTo: and passes subject. I think it would make things more seamless regarding ValueKeyedAdaptors or ValueKeyedAdaptors, in fact they could even be mixed (not likely needed, but who knows). I may not actually do this since I don't really want to make these kinds of system changes. However OA might consider doing something like this as a future enhancement to better support keyed collections in MVP Dialogs. Chris Frank Sergeant <[hidden email]> wrote in message news:X13g6.759$[hidden email]... > Oops, I left some information out from my previous post. (And, may well > still be leaving something out.) > > > I think I am going to try adding DNU support to my record class, so I can > > use the existing aspectValue: message. > > That shouldn't be necessary. Following is an example #model: from one of my > subclasses of Dialog. The superclass (Dialog) takes care of creating the > buffered model. For this to work, I added two methods to AspectBuffer > (#keyedApply and #keyedAspectValue: ) then override #apply in the Dialog > subclass to have it send #keyedApply to the model instead of #apply. > > ------------------------ > model: aSubjectModel > > "Set the model of the receiver to be a buffer onto of aSubjectModel." > > | aspectBuffer | > > super model: aSubjectModel. > > " ** now wire up the sub models automatically ** " > > aspectBuffer := self model. > > subPresenters do: [:each | > > aspectBuffer value at: (self nameOf: each) asSymbol ifPresent: [:what | > > each model: (aspectBuffer keyedAspectValue: (self nameOf: each) > asSymbol)]]. > > > ------------------------ > > AspectBuffer>>keyedApply > "Apply the aspects held by the receiver in the model copy back to the > original model" > > aspects do: [:each | > > self subject perform: each putSelector with: each key with: each > > ------------------------ > AspectBuffer>>keyedAspectValue: aKey > > "Answer a ValueAspectAdapter for anAspectSymbol of our copied model. If a > request for this aspect has already been registered then the same adapter > model is answered. Otherwise a new one is created and registered in our > aspects dictionary. This is the same as #aspectValue: except that the aspect > symbol is a key rather than an attribute." > > ^aspects at: aKey ifAbsentPut: [ > > ValueKeyedAdaptor subject: subjectCopy "aspect:" key: aKey] > > ------------------------ > > > -- Frank > [hidden email] > |
"Christopher J. Demers" <[hidden email]> wrote in
message news:95t2nv$ibbqe$[hidden email]... > Thanks, this is exactly what I was after. ... > I have followed your example and it works, thank you! I am delighted to have provided something useful! > I just wanted to make sure I was working the way MVP > wants me to work. I wonder if OA might consider adding something like this > to the base system? It looks like Dolphin has the beginnings of what we > need but stops just short of the full implementation (at least for Dialogs). Things have been going increasingly smoothly for me in Dolphin as I have gotten more familiar with it. It required a heavy investment in start-up effort for me to do so, especially regarding building (and connecting) GUIs. This was *after* I thought I knew Smalltalk and thought I understood the equivalent GUI building in both VisualWorks and Visual Age. The first point (thinking I knew Smalltalk) could be explained by noting that I have continued to learn a great deal about using the built-in Smalltalk environment to answer questions, but it doesn't fully explain the 2nd and 3rd points (re "getting it" in VW and VA). It could be that I had a blind spot causing me trouble but that others fall into the Dolphin way without effort. The above paragraph is rather a disclaimer to my suggestion that maybe Dolphin's GUI approach could be improved further. We are used to the stupid newbie coming in and suggesing all sorts of wild "improvements" before he has a clue. However, I hope I am no longer he. I think the most needed thing is not so much a change to Dolphin, but improved and additional documentation and examples. Various posters have been very helpful in providing examples and answering questions. I am looking forward to one or more Dolphin books. If it had the number of books that VW has, giving examples and explanations, Dolphin would be far easier to "get into". Well, we really have enough now so that Dolphin *can* be learned, it just takes some digging, but more would be even better. I need to look into it more, but I am somewhat unhappy that the dialog and non-dialog windows are so segregated. I believe OA have offered reasons for this but all I got out of it was "Microsoft suggests it so it's got to be good" (unfair, incorrect summary for rhetorical purposes). What I want instead (I think) is a simple boolean to say whether the window is modal or not. I do not see how the difference of model (sometimes you want a buffered model and sometimes not, sometimes you want to wait for an answer and sometimes not) justifies this separation. Of course, I could be overlooking important factors, so I want to look into it further before committing myself. Also, the various window creation methods seem needlessly complex (or maybe I just just need a thorough explanation). I think Dolphin is so very good that there is nothing stopping us from having it be perfect. My role, of course, is to point out possible problems, or conveniences available in other environments, and then see them appear magically. With the base OA work plus Ian's ViewComposer additions, we have much of the convenience of the very expensive but very good WindowBuilderPro. Things are so good that I am not sure what to ask for next! (Well, abstracting the GUI from its Windows implementation, without losing any speed, thus paving the way for a port to Linux, is something you could put on your "to do" list for when you didn't have anything better to do.) -- Frank [hidden email] I did not have sex with that woman |
Frank Sergeant <[hidden email]> wrote in message
news:rfFg6.947$[hidden email]... > > Things have been going increasingly smoothly for me in Dolphin as I have > gotten more familiar with it. It required a heavy investment in start-up > effort for me to do so, especially regarding building (and connecting) GUIs. > This was *after* I thought I knew Smalltalk and thought I understood the > equivalent GUI building in both VisualWorks and Visual Age. The first point Yep, me too on this front. My big problem at first was that I knew just enough to be dangerous with Dolphin GUI's. I knew how to refer to views via viewNamed: so I thought I had no need for sub-presenters. I just threw my data in the views, and grabbed it back when I was done. It worked, and I had to make some GUI's, so I just did them that way. Sometimes it is hard to stop and learn the "right" way once you get going one way. Now I understand the reason for all the sub-presenters. However I still did not want to type all the presenter support code manually. I wrote a class to do that for me. It walks the view and gets all named sub-views that need presenters. Then it adds the instance variables to the class, and generates a createComponents method for the class using a view class to presenter class mapping dictionary. If I can get the code polished a bit more, and there is interest I might make it available as a free goodie. > I think the most needed thing is not so much a change to Dolphin, but > improved and additional documentation and examples. Various posters have > been very helpful in providing examples and answering questions. I am > looking forward to one or more Dolphin books. If it had the number of books Definitely! I would love to see a comprehensive Dolphin book as well as improved documentation. > > I need to look into it more, but I am somewhat unhappy that the dialog and > non-dialog windows are so segregated. I believe OA have offered reasons for I think OA made some changes in this area in version 4.0. I know because it broke my code. ;) I used to use Dialog<<show to open my dialogs in 3.0 and it worked because it effectively just sent Dialog<<showModal. In version 4 they removed Dialog<<show and it now uses Presenter<<show which will open a non-modal dialog. This may not be totally what you are after, but it might be part of it. I have had cases where I made a view in the wrong part of the hierarchy, and needed to move it. I found that I could move the presenter class, and then mutate the view as needed (after I patched the mutate code so it does not loose sub-view names). > > I think Dolphin is so very good that there is nothing stopping us from > having it be perfect. My role, of course, is to point out possible Cheers to a perfect Dolphin, or as close to it as mortals dare tread! Chris |
In reply to this post by Frank Sergeant
Frank,
> I need to look into it more, but I am somewhat unhappy that the dialog and > non-dialog windows are so segregated. I believe OA have offered reasons for > this but all I got out of it was "Microsoft suggests it so it's got to be > good" (unfair, incorrect summary for rhetorical purposes). What I want > instead (I think) is a simple boolean to say whether the window is modal or > not. I do not see how the difference of model (sometimes you want a > buffered model and sometimes not, sometimes you want to wait for an answer > and sometimes not) justifies this separation. Of course, I could be > overlooking important factors, so I want to look into it further before > committing myself. FWIW, I agree with you. There shouldn't really be a need, on the presenter side, to distinuguish between a dialog and a shell. A dialog does usually need to buffer changes to its model and the #accept code has to go somewhere so that's whay we created the Dialog subclass of Shell. It's possible that this could be dispensed with but what impact this would have on existing code, I don't know. We would still need to keep the idea of a DialogView separately from a ShellView, however. This is a Windows issue since the OS treats "real" dialogs quite differentlly from top level windows. We don't really want to get into the business of not using a real dialg and simulating the modal behaviour since this doesn't fit with the "spirit" of Dolphin. Best Regards, Andy Bower Dolphin Support http://www.object-arts.com --- Visit the Dolphin Smalltalk WikiWeb http://www.object-arts.com/wiki/html/Dolphin/FrontPage.htm --- |
"Andy Bower" <[hidden email]> wrote in message
news:960dtj$i9fpg$[hidden email]... [re segregating Dialog and Shell windows] > FWIW, I agree with you. There shouldn't really be a need, on the presenter > side, to distinuguish between a dialog and a shell. ... > It's possible that this could be dispensed with but what impact this would have on existing > code, I don't know. Right, thanks, and I see your point about existing code. No particular rush on my part, just something to consider and possibly aim for eventually. > We would still need to keep the idea of a DialogView separately from a > ShellView, however. Ok, that doesn't seem like a problem to me. > This is a Windows issue since the OS treats "real" > dialogs quite differentlly from top level windows. We don't really want to > get into the business of not using a real dialg and simulating the modal > behaviour since this doesn't fit with the "spirit" of Dolphin. I accept that. <wink> By the way, Borland seems to think there is big money in Linux. I just got an ad for Kylix listing the big version ("server" development version, or some such) for around $2000 (USD) and the little version ("desktop" development version, or some such) for around $1000 (USD), but offering several hundred dollars off if I buy right away. Well, I think they are making a mistake. Linux is the home (one of the homes) of *free* software. One of us is going to be surprised, and I think it is going to be Borland, but I've been wrong before. If Borland is right, maybe you should raise the priority of a Linux port of Dolphin. If I am right, there is hardly any point to doing the port just for Steve and me. -- Frank [hidden email] |
Free forum by Nabble | Edit this page |