Hello all,
I am building a form that consists of two components, e.g. House and Person. For each of these, when a new one is created I register it. I have a manager class that displays these using: MAToManyRelationDescription new classes: (Array with: House); label: 'Houses'; accessor: (MASelectorAccessor new readSelector: #houses; writeSelector: nil; yourself); default: Array new; priority: 20; yourself People is similar. The Manager class is a form, but with no buttons as it is only needed to let the add buttons work on these relation descriptions. The accessor shown here, houses just calls "House instances" to get currently registered houses. I subclass MACheckedMemento and create a custom memento that simply overrides the #push: method to see if the object is new (no members will be set) and if so, registers the object after called "super push:". Everything is fine except for Houses, after I create a new hause the main display always shows 2. If I leave the page and visit new I see only one. I have looked around but I dont see how this is happening. Any ideas? _______________________________________________ SmallWiki, Magritte, Pier and Related Tools ... https://www.iam.unibe.ch/mailman/listinfo/smallwiki |
Hi,
> I am building a form that consists of two components, e.g. House and > Person. For each of these, when a new one is created I register it. what do you register? And -- when you create new ones -- you have more than two components? I don't quite get it ... > I have a manager class that displays these using: That's the form? > MAToManyRelationDescription new > classes: (Array with: House); > label: 'Houses'; > accessor: (MASelectorAccessor new > readSelector: #houses; > writeSelector: nil; > yourself); > default: Array new; > priority: 20; > yourself > > People is similar. The Manager class is a form, but with no buttons > as it is only needed to let the add buttons work on these relation > descriptions. The accessor shown here, houses just calls "House > instances" to get currently registered houses. I subclass > MACheckedMemento and create a custom memento that simply overrides the > #push: method to see if the object is new (no members will be set) and > if so, registers the object after called "super push:". Why don't you write your manager class manually and display the editors for houses and persons as children? You can use the #onAnswer: handler of the Magritte components to get notified when the user hits add (save). I don't quite understand why you need MAToManyRelationDescription and a custom MACheckedMemento. Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch _______________________________________________ SmallWiki, Magritte, Pier and Related Tools ... https://www.iam.unibe.ch/mailman/listinfo/smallwiki |
Sorry, I was in a hurry because I had to get off the train. :)
Ok, I have a Person class and a House class. Each of these has a class side method called #register: that stores the instance in an ordered collection of the class side. Person and House both have full descriptions and are capable of displaying themselves, so the "manager" class just allows one to make many of these. So the use case is, you see the first page, it has a list of Persons and a list of Houses, these are queried from the instances registered with the class (i.e. in the class side collection variable). The user clicks "add" on, say, Person. Now they get the Person page, as described by the Person class, they type in there information and click "Save". This is where I need the custom memento (and tell me if I'm doing this wrong): If you click save that winds up calling "commit" on the memento and actually writing the data to the object, but this new object wont be registered in the class side collection (and therefor will simply cease to exist when this session expires). So my custom memento simply lets everything work as normal and then calls "Person register: self model" to get the new object registered. The problem happens when "save" returns on Person and you go back to the manager page. You see your nice new Person in the report table as expected, but right below is the same Person again! And if you edit either one the changes reflect in both. And the really hairy thing is, even though House is almost exactly the same in every way (I can find no relevant difference) it doesn't have this behavior. (couple of comments below as well) On Nov 20, 2007 9:36 PM, Lukas Renggli <[hidden email]> wrote: > > That's the form? Below was the description that the manager uses to show the list of Houses. > > MAToManyRelationDescription new > > classes: (Array with: House); > > label: 'Houses'; > > accessor: (MASelectorAccessor new > > readSelector: #houses; > > writeSelector: nil; > > yourself); > > default: Array new; > > priority: 20; > > yourself > > > Why don't you write your manager class manually and display the > editors for houses and persons as children? You can use the #onAnswer: > handler of the Magritte components to get notified when the user hits > add (save). Hrm, I thought that's what I was doing. The above description is saved in the manager as a component under houseComponent and is returned from the children method of the manager. But I will go look up uses of onAnswer to try and figure out what you mean. _______________________________________________ SmallWiki, Magritte, Pier and Related Tools ... https://www.iam.unibe.ch/mailman/listinfo/smallwiki |
> Ok, I have a Person class and a House class. Each of these has a
> class side method called #register: that stores the instance in an > ordered collection of the class side. Person and House both have full > descriptions and are capable of displaying themselves, so the > "manager" class just allows one to make many of these. Ok, got it. > This is where I need the custom memento (and tell me if I'm doing this > wrong): If you click save that winds up calling "commit" on the > memento and actually writing the data to the object, but this new > object wont be registered in the class side collection (and therefor > will simply cease to exist when this session expires). So my custom > memento simply lets everything work as normal and then calls "Person > register: self model" to get the new object registered. Sure that's a possibility, but why not use the return value if you are using #call: or set an #onAnswer: handler if you are using composition? So in your manager you have something along: house := self call: House new asComponent. house ifNotNil: [ House register: house ]. or (in case of composition): editor := House new asComponent onAnswer: [ :house | house ifNotNil: [ House register: house ]. editor := nil ] > The problem happens when "save" returns on Person and you go back to > the manager page. You see your nice new Person in the report table as > expected, but right below is the same Person again! And if you edit > either one the changes reflect in both. And the really hairy thing > is, even though House is almost exactly the same in every way (I can > find no relevant difference) it doesn't have this behavior. Looks like your memento method gets called twice? Why not check if the object is already present? Why not use a Set then? Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch _______________________________________________ SmallWiki, Magritte, Pier and Related Tools ... https://www.iam.unibe.ch/mailman/listinfo/smallwiki |
Thanks for the response. Sorry I was so long in getting back to this.
December is a pretty insane month for me at the moment. :) (comments below) On Nov 29, 2007 8:00 AM, Lukas Renggli <[hidden email]> wrote: > > > This is where I need the custom memento (and tell me if I'm doing this > > wrong): If you click save that winds up calling "commit" on the > > memento and actually writing the data to the object, but this new > > object wont be registered in the class side collection (and therefor > > will simply cease to exist when this session expires). So my custom > > memento simply lets everything work as normal and then calls "Person > > register: self model" to get the new object registered. > > Sure that's a possibility, but why not use the return value if you are > using #call: or set an #onAnswer: handler if you are using composition? Well, the thing is, I'm using a shortcut here. :) The manager just basically provides a web page that allows one to use the descriptions of other two. It doesn't use call because it doesn't want anything back. Maybe an example will make it clearer. Manager>>renderContentOn: html html render: self component >>component ^ component ifNil: [ component := ((self housesComponent, self peopleComponent) asComponentOn: self) addForm: #(); "I don't want any buttons on this form since submitting it would make no sense, I do nothing with the values here" yourself ] "since the House and Person classes manage their own instances" >>housesComponent "gives a nice view for managing houses" ^ MAToManyRelationDescription new classes: (Array with: House); label: 'Houses'; accessor: (MASelectorAccessor new readSelector: #houses; writeSelector: nil; yourself); default: Array new; priority: 20; yourself >>peopleComponent "ditto for people" ^ MAToManyRelationDescription new classes: (Array with: Person); label: 'People'; accessor: (MASelectorAccessor new readSelector: #people; writeSelector: nil; yourself); default: Array new; priority: 20; yourself >>houses ^ House instances >>people ^ Person instances > So in your manager you have something along: > > house := self call: House new asComponent. > house ifNotNil: [ House register: house ]. > > or (in case of composition): > > editor := House new asComponent onAnswer: [ :house | > house ifNotNil: [ House register: house ]. > editor := nil ] This I tried. It doesn't work when I put it on #houseComponent or #storeComponent since I'm using #, and when I put it in #component it seems to be ignored. > > The problem happens when "save" returns on Person and you go back to > > the manager page. You see your nice new Person in the report table as > > expected, but right below is the same Person again! And if you edit > > either one the changes reflect in both. And the really hairy thing > > is, even though House is almost exactly the same in every way (I can > > find no relevant difference) it doesn't have this behavior. > > Looks like your memento method gets called twice? Why not check if the > object is already present? Why not use a Set then? Ah but I do. Since I'm in the momento I have to check if there already exists an object that has the same value as the ones cached in the momento. I had a #break call in the momento and I'm sure it's not getting called twice, which wouldn't hurt anything if it did. It seems like the MA machinery is doing some caching of some kind. The part that baffles me is that it doesn't happen for Houses, even though they are fundamentally exactly the same. I suppose this would be so much easier if I just let Magritte manage everything completely, but this code gets managed in other places then on these web pages. > > > Cheers, > Lukas > > -- > Lukas Renggli > http://www.lukas-renggli.ch > > > _______________________________________________ > SmallWiki, Magritte, Pier and Related Tools ... > https://www.iam.unibe.ch/mailman/listinfo/smallwiki > _______________________________________________ SmallWiki, Magritte, Pier and Related Tools ... https://www.iam.unibe.ch/mailman/listinfo/smallwiki |
Free forum by Nabble | Edit this page |