Lukas Renggli schrieb:
if an Object
holds a collection of other Objects (like a group of
Persons), and
these (Persons) should not be created/edited but a list to choose
from should be
presented - would a MAMultipleOptionDescription be appropriate? If
so, how can
the options presented be made dynamic.
There are several ways to make properties of descriptions dynamic.
1. Override #description on the instance-side and build your
descriptions programmatically. Don't forget to copy the descriptions,
in case you call super to get modify the default behavior.
2. Pass the property a block that you send #asDynamicObject. See the
senders of this message for examples. This approach is simple and works
in most cases, there are some possible drawbacks however: (1) the
implementation uses a proxy object that might not get properly resolved
in all cases, (2) the proxy object references a block context that
might not be serializeable with your preferred persistency mechanism,
(3) proxies are hard to debug, and (4) from within the block you don't
have access to the described object.
Hi,
thanks a lot for the suggestions! I tried some things and would like to share my
experiences here:
[1.] was obvious (after having worked through your exercises at least) but not
very elegant.
I started experimenting with asDynamicObject but in case of
MASingleOptionDescription >> optionsAndLabels: it was not of any use, as the
Collection passed in gets copied, and so the proxy object is lost.
Now simply trying to use MASingleOptionDescription >> options: (providing the
label through model >> printString) raised other questions:
The defaultReference used by the MAOptionDescriptions is a MAStringDescription
which tells a visitor to use the visitStringDescription: method. In case of the
MAStringWriter this is implemented as:
MaStringWriter >> visitStringDescription: aDescription
self stream nextPutAll: self object
This obviously fails in cases where object is no String. visitElementDescription
adds asString which works :
MaStringWriter >> visitElementDescription: aDescription
self stream nextPutAll: self object asString
MAElementDescription however isAbstract and therefore can't be used for
MASingleOptionDescription >> reference:
I could work around by creating a new description class and corresponding
MAStringWriter subclass then setting the reference attribute to it:
MASingleOptionDescription new
label: 'Label' ;
reference: MAMyStringDescription new;
selectorAccessor: #myAccessor;
options: [WAPersonManager persons]asDynamicObject;
Then MAPersonModel >> printString returns lastName or something useful.
That way everything works fine and the choices are dynamic (hitting reload in
the browser updates the list)
To make this work out of the box, maybe 'asString' should be added to
MaStringWriter >> visitStringDescription:
- Or a better defaultReference could be choosen for MAOptionDescription subclasses.
I hope this made sense... Cheers, Christoph