Ok...I'm not looking for an answer, just maybe a recommendation on how to proceed.
I created a very simple "dynamic object" (aren't all Smalltalk objects dynamic?!) with an addField method that would create a new instance variable and accessors so that I could dynamically add new input fields to a WebApplication (since a WebFormElement uses an aspect:for: an object to bind to--otherwise, I probably would just use a Dictionary). Anyway, I just used my novice understanding to do something like: ArbitraryObject>>class #addField | aFieldName| aFieldName := self newFieldName. self addInstVarName: aFieldName. self addGetter: aFieldName. self addSetter: aFieldName. ^aFieldName asSymbol. creating an arbitrary field name "fieldN" with: ArbitraryObject>>class #newFieldName ^'field',self newNumber asString. and ArbitraryObject>>class #newNumber Counter ifNil: [^Counter:=1]. ^Counter:=Counter+1. and compiling accessors with: ArbitraryObject>>class #addGetter: fieldName |method| method:=fieldName,' ^',fieldName. self compile: method classified: 'field accessors'. and ArbitraryObject>>class #addSetter: fieldName |method | method:=fieldName,': anObject ^',fieldName,':=anObject'. self compile: method classified: 'field accessors' (I know...there is a method SOMEWHERE that will do that for me!) Anyway, it works fine if I simple execute the addField on the object from within a Workspace or something, but if I do it from within it's application (say in an action method for a button on the page), the addField method does not complete, the web page just dies, and I don't even get an error message. So then I tried having such an object be contained within the domain object and had the same result. So... 1. Can you simply bind, say, a WebInputField to ANY object (not an aspect of an object), in which case I could store my dynamic fields in a collection of some kind, or 2. Is there any reason you can think of why Aida wouldn't like it's objects being recompiled in the middle of a page refresh? Thanks, Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
Hi Rob,
On Thu, 22 May 2008 18:57:51 -0400 "Rob Rothwell" <[hidden email]> wrote: > Ok...I'm not looking for an answer, just maybe a recommendation on how to > proceed. > > I created a very simple "dynamic object" (aren't all Smalltalk objects > dynamic?!) with an addField method that would create a new instance variable > and accessors so that I could dynamically add new input fields to a > WebApplication (since a WebFormElement uses an aspect:for: an object to bind > to--otherwise, I probably would just use a Dictionary). FWIW, I *would* use a dictionary. An "aspect" is nothing more than a reader and a writer with "compatible" names. If your ArbitraryObject has a dictionary 'properties' as instance variable, you can create "aspects" of your ArbitraryObject like, e.g. name ^properties at: #name ifAbsent: ['unnamed'] name: aString properties at: #name put: aString If you don't care too much for speed, you could also avoid defining all of these methods by yourself (or explicitly in code) and instead prevent the MNU exception being raised by implementing (in VW) Object's method 'doesNotUnderstand: aMessage' which gives you access to the selector, which in turn would point to the property you're interested in. HTH, s. _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Rob Rothwell
Hi Rob,
Another solution, better IMHO, would be to use dynamic variables. Let me explain a bit: If you store your custom variables in a dictionary, then in Aida you can simply add an entry for each variable. AObject>>dynamicVariables dynamicVariables isNil ifTrue: [self initDynamicVariables]. ^dynamicVariables AObject>>initDynamicVariables dynamicVariables := Dictionary new To add a custom variable: AObject>>addDynamicVariable: aString value: anObject self dynamicVariables at: aString put: [anObject] Of course it can be improved, but that's the idea. Then in Aida you can view or edit all of them: AObjectApp>>viewMain .... self observee dynamicVariables do: [:each | e addtext: each key, ': ', each value; addBreak]. .... Cheers! Nico -- Nicolas Petton http://nico.bioskop.fr ___ ooooooo OOOOOOOOO |Smalltalk| OOOOOOOOO ooooooo \ / [|] -------------------------------- Ma clé PGP est disponible ici : http://nico.bioskop.fr/pgp-key.html _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida signature.asc (204 bytes) Download Attachment |
In reply to this post by Stefan Schmiedl
Le vendredi 23 mai 2008 à 01:09 +0200, Stefan Schmiedl a écrit : > Hi Rob, > > On Thu, 22 May 2008 18:57:51 -0400 > "Rob Rothwell" <[hidden email]> wrote: > > > Ok...I'm not looking for an answer, just maybe a recommendation on how to > > proceed. > > > > I created a very simple "dynamic object" (aren't all Smalltalk objects > > dynamic?!) with an addField method that would create a new instance variable > > and accessors so that I could dynamically add new input fields to a > > WebApplication (since a WebFormElement uses an aspect:for: an object to bind > > to--otherwise, I probably would just use a Dictionary). > > FWIW, I *would* use a dictionary. Nico > An "aspect" is nothing more than > a reader and a writer with "compatible" names. If your ArbitraryObject > has a dictionary 'properties' as instance variable, you can create > "aspects" of your ArbitraryObject like, e.g. > > name > ^properties at: #name ifAbsent: ['unnamed'] > > name: aString > properties at: #name put: aString > > If you don't care too much for speed, you could also avoid defining all > of these methods by yourself (or explicitly in code) and instead prevent > the MNU exception being raised by implementing (in VW) > Object's method 'doesNotUnderstand: aMessage' which gives you access > to the selector, which in turn would point to the property you're > interested in. > > HTH, > s. > _______________________________________________ > Aida mailing list > [hidden email] > http://lists.aidaweb.si/mailman/listinfo/aida _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida signature.asc (204 bytes) Download Attachment |
On Fri, 23 May 2008 01:22:00 +0200
Nicolas Petton <[hidden email]> wrote: > You was faster than me! :) heheh ... reading emails just before going to bed has its merits :-) s. _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Nicolas Petton
On Thu, May 22, 2008 at 7:20 PM, Nicolas Petton <[hidden email]> wrote:
Hi Rob, This part I can actually do myself, and in Aida, I even understand... AObjectApp>>viewMain AObjectApp>>viewMain | field | ..... self observee dynamicVariables do: [:each | field := WebInputField new aspect: ??? for: self observee dynamicVariables size: 50. e add: field. e addBreak]. I think I am missing something fundamental again...I mean, I do not know the "aspect" until the user creates it... Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Stefan Schmiedl
On Thu, May 22, 2008 at 7:09 PM, Stefan Schmiedl <[hidden email]> wrote:
FWIW, I *would* use a dictionary. An "aspect" is nothing more than I actually started to do just what you have written above, but in Aida, I STILL need the methods to be defined, so if I am creating new methods "on the fly," wouldn't I either still need to recompile an object or do what you mentioned below? If you don't care too much for speed, you could also avoid defining all Thanks for the doesNotUnderstand idea, though...I hadn't thought of that having listened to all the pro's and con's of such usage a while back on the lists! _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
On Thu, 22 May 2008 19:31:28 -0400
"Rob Rothwell" <[hidden email]> wrote: > I actually started to do just what you have written above, but in Aida, I > STILL need the methods to be defined, so if I am creating new methods "on > the fly," wouldn't I either still need to recompile an object or do what you > mentioned below? If I read your mind correctly, medidate about the following sentence: You don't need to have a method defined for your objects, a receiver only needs to be able to handle an incoming message. In many other languages, this distinction does not exist, because of static type checking and what not else. In Smalltalk (and friends, like ruby), it's important. Besides this, you're right. You have to define the accessors somewhere. However, how about defining a method WebFormElement>>dynamicProperty:of: similar to the way aspect:for: works, but instead of mapping the symbol to an immediate accessor, use it to access the observee's property dictionary. > Thanks for the doesNotUnderstand idea, though...I hadn't thought of that > having listened to all the pro's and con's of such usage a while back on the > lists! Yeah, well, just like most things, it's a powerful tool to be used with care. s. _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
On Fri, May 23, 2008 at 9:08 AM, Stefan Schmiedl <[hidden email]> wrote:
On Thu, 22 May 2008 19:31:28 -0400 I actually do understand that part, but because of the internals of how Aida works (if I understand it correctly), The XyzApp object that is "bound" to my Xyz object will load/store the WebFormElement data by sending them a [pre]defined message. By definition, all my [dynamic] messages will be "undefined." Besides this, you're right. You have to define the accessors somewhere. So, what I am working on is basically a combination of what you have suggested...a new dynamicProperty:of: method that gets activated by doesNotUnderstand: so that Aida can continue to function normally... Thanks for the ideas! Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
On Fri, 23 May 2008 09:38:51 -0400
"Rob Rothwell" <[hidden email]> wrote: > > However, how about defining a method > > > > WebFormElement>>dynamicProperty:of: > > > > similar to the way aspect:for: works, but instead of mapping the symbol > > to an immediate accessor, use it to access the observee's property > > dictionary. > > > So, what I am working on is basically a combination of what you have > suggested...a new dynamicProperty:of: method that gets activated by > doesNotUnderstand: so that Aida can continue to function normally... I've just taken a look at how aspect:for: was implemented, which led me to the method WebFormElement>>adapt adapt "set appropriate aspect adaptor for that element" (self aspect isKindOf: Symbol) ifTrue: [self adaptor: ((AIDAAspectAdaptor forAspect: self aspect) subject: self object)]. (self aspect isKindOf: Number) ifTrue: ["adapt to an element of collection" self adaptor: ((AIDAIndexedAdaptor forIndex: self aspect) subject: self object)] which is kind of ugly (sorry Janko). I might be wrong, but it looks like adapt is called on all WebFormElements, so you probably can't just define your own adaptor like self adaptor: ((AIDAIndexedAdaptor forIndex: self aspect) subject: self object properties OTOH, it gives me an idea: It would work out of the box, if the object behind the form is a collection indexable by numbers. Can you put your dynamic properties into an OrderedCollection and use this collection as model for a "dynamic property editor" component? s. _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Rob Rothwell
Rob Rothwell wrote:
> I actually do understand that part, but because of the internals of how > Aida works (if I understand it correctly), The XyzApp object that is > "bound" to my Xyz object will load/store the WebFormElement data by > sending them a [pre]defined message. By definition, all my [dynamic] > messages will be "undefined." This "aspect adapting" is done with help of AIDAAspectAdaptor (in Aida-Support). It is done by calling yourApp form #registerFormElementsIn: anElement. All form elements are then registered in instvar #fields in yourApp form. Aspect adaptor is otherwise a pattern from MVC implementation in VisualWorks by which Aida design is heavily influenced anyway. See Smalltalk An Introduction to Application Development using VisualWorks, Chapter 29 (page 312): Introduction to Models, Views and Controllers: http://stephane.ducasse.free.fr/FreeBooks/HopkinsHoran/HopkinsHoran.pdf I would say that with extending that aspect adapting pattern you can actually achieve your goals easily. Even more because we already have auto converting of values supported already (see WebFormElement class auto type converting) Janko -- Janko Mivšek AIDA/Web Smalltalk Web Application Server http://www.aidaweb.si _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Stefan Schmiedl
On Fri, May 23, 2008 at 10:05 AM, Stefan Schmiedl <[hidden email]> wrote:
OTOH, it gives me an idea: It would work out of the box, if the object Oh...I think you're right...it looks like if you pass a number as the aspect it assumes the object is an indexed collection?! adapt "set appropriate aspect adaptor for that element" (self aspect isKindOf: Symbol) ifTrue: [self adaptor: ((AIDAAspectAdaptor forAspect: self aspect) subject: self object)]. (self aspect isKindOf: Number) ifTrue: "adapt to an element of collection" [self adaptor: ((AIDAIndexedAdaptor forIndex: self aspect) subject: self object)] I would be quite happy to map my fields to open slots in a collection for now! Thanks...hope that works... Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Janko Mivšek
On Fri, May 23, 2008 at 10:12 AM, Janko Mivšek <[hidden email]> wrote:
This "aspect adapting" is done with help of AIDAAspectAdaptor (in Aida-Support). It is done by calling yourApp form #registerFormElementsIn: anElement. All form elements are then registered in instvar #fields in yourApp form. Thanks for the references...I will try the simplest thing for now (indexed values) and see how that works! Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
In reply to this post by Janko Mivšek
On Fri, May 23, 2008 at 10:12 AM, Janko Mivšek <[hidden email]> wrote:
I would say that with extending that aspect adapting pattern you can actually achieve your goals easily. Even more because we already have auto converting of values supported already (see WebFormElement class auto type converting) Looking deeper, though, it looks like each WebFormElement can resolve it's bindings in it's own way. For example, WebCheckBox sends the aspect message directly to the "bound" object even when I "bind" it to an object in a collection: isChecked | value | self aspect notNil ifTrue: [value := self object perform: self aspect. ^value == true]. "so that false will be returned even if value is not so" self selected notNil ifTrue: [^self selected includes: self object]. ^self checked It sure looks like the least common denominator is a named message...the doesNotUnderstand route is looking better all the time...though probably not an elegant solution...! Thanks again, Rob _______________________________________________ Aida mailing list [hidden email] http://lists.aidaweb.si/mailman/listinfo/aida |
Free forum by Nabble | Edit this page |