Re: [flexcoders] Re: Updating renderer properties
I know this is an old thread, but for those who come across this in the future, this is a great article that sums up the problem and solutions quite well: http://www.adobe.com/devnet/flex/articles/itemrenderers_pt3_02.html Aaron On Fri, Jan 8, 2010 at 10:47 PM, Aaron Hardy aaronius...@gmail.com wrote: Thanks for sharing your thoughts and examples. In my case I decided to pass in a model with a property into the renderers. The model is passed into the renderer by specifying it as a property value in the renderer class factory. The model doesn't ever get replaced after that, but the property inside the model does. I can't say any solution really strikes my fancy, but this seemed to be the most appropriate. Again, thanks for the discussion. Aaron On Fri, Jan 8, 2010 at 9:07 AM, valdhor valdhorli...@embarqmail.comwrote: I set up a quick test bed based on your original post and using a static variable in the renderer(s) and it worked rather well. It may not be what you are after but I will post the example here for others that may want to use this. Application: ?xml version=1.0 encoding=utf-8? mx:Application xmlns:mx=http://www.adobe.com/2006/mxml; layout=vertical width=700 mx:Script ![CDATA[ import mx.collections.ArrayCollection; import Renderers.CityRenderer; import Renderers.CompanyRenderer; [Bindable] public var initDG:ArrayCollection = new ArrayCollection([ {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, ]); private function setColors():void { CityRenderer.textColor = #FF; CompanyRenderer.textColor = #FF; initDG.refresh(); } private function resetColors():void { CityRenderer.textColor = #00; CompanyRenderer.textColor = #00; initDG.refresh(); } ]] /mx:Script mx:DataGrid id=myGrid rowHeight=22 dataProvider={initDG} rowCount={initDG.length} mx:columns mx:DataGridColumn dataField=Company itemRenderer=Renderers.CompanyRenderer/ mx:DataGridColumn dataField=Contact/ mx:DataGridColumn dataField=Phone/ mx:DataGridColumn dataField=City width=150 itemRenderer=Renderers.CityRenderer/ /mx:columns /mx:DataGrid mx:HBox mx:Button label=Set Colors click=setColors()/ mx:Button label=Reset Colors click=resetColors()/ /mx:HBox /mx:Application CityRenderer.as: package Renderers { import mx.controls.*; import mx.controls.dataGridClasses.DataGridListData; public class CityRenderer extends Text { public static var textColor:String = #00; public function CityRenderer() { super(); } override public function set data(value:Object):void { super.data = value; if(value != null) { text = value[DataGridListData(listData).dataField]; } } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); setStyle(color, CityRenderer.textColor); } } } CompanyRenderer.as: package Renderers { import mx.controls.*; import mx.controls.dataGridClasses.DataGridListData; public class CompanyRenderer extends Text { public static var textColor:String = #00; public function CompanyRenderer() { super(); } override public function set data(value:Object):void { super.data = value; if(value != null) { text = value[DataGridListData(listData).dataField]; } } override protected function
Re: [flexcoders] Re: Updating renderer properties
Thanks for sharing your thoughts and examples. In my case I decided to pass in a model with a property into the renderers. The model is passed into the renderer by specifying it as a property value in the renderer class factory. The model doesn't ever get replaced after that, but the property inside the model does. I can't say any solution really strikes my fancy, but this seemed to be the most appropriate. Again, thanks for the discussion. Aaron On Fri, Jan 8, 2010 at 9:07 AM, valdhor valdhorli...@embarqmail.com wrote: I set up a quick test bed based on your original post and using a static variable in the renderer(s) and it worked rather well. It may not be what you are after but I will post the example here for others that may want to use this. Application: ?xml version=1.0 encoding=utf-8? mx:Application xmlns:mx=http://www.adobe.com/2006/mxml; layout=vertical width=700 mx:Script ![CDATA[ import mx.collections.ArrayCollection; import Renderers.CityRenderer; import Renderers.CompanyRenderer; [Bindable] public var initDG:ArrayCollection = new ArrayCollection([ {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, {Company: 'Allied', Contact: 'Jane Smith', Phone: '617-555-3434', City: 'SanFrancisco', State: 'CA'}, {Company: 'Acme', Contact: 'Bob Jones', Phone: '413-555-1212', City: 'Boston', State: 'MA'}, ]); private function setColors():void { CityRenderer.textColor = #FF; CompanyRenderer.textColor = #FF; initDG.refresh(); } private function resetColors():void { CityRenderer.textColor = #00; CompanyRenderer.textColor = #00; initDG.refresh(); } ]] /mx:Script mx:DataGrid id=myGrid rowHeight=22 dataProvider={initDG} rowCount={initDG.length} mx:columns mx:DataGridColumn dataField=Company itemRenderer=Renderers.CompanyRenderer/ mx:DataGridColumn dataField=Contact/ mx:DataGridColumn dataField=Phone/ mx:DataGridColumn dataField=City width=150 itemRenderer=Renderers.CityRenderer/ /mx:columns /mx:DataGrid mx:HBox mx:Button label=Set Colors click=setColors()/ mx:Button label=Reset Colors click=resetColors()/ /mx:HBox /mx:Application CityRenderer.as: package Renderers { import mx.controls.*; import mx.controls.dataGridClasses.DataGridListData; public class CityRenderer extends Text { public static var textColor:String = #00; public function CityRenderer() { super(); } override public function set data(value:Object):void { super.data = value; if(value != null) { text = value[DataGridListData(listData).dataField]; } } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); setStyle(color, CityRenderer.textColor); } } } CompanyRenderer.as: package Renderers { import mx.controls.*; import mx.controls.dataGridClasses.DataGridListData; public class CompanyRenderer extends Text { public static var textColor:String = #00; public function CompanyRenderer() { super(); } override public function set data(value:Object):void { super.data = value; if(value != null) { text = value[DataGridListData(listData).dataField]; } } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); setStyle(color, CompanyRenderer.textColor); } } } --- In flexcoders@yahoogroups.com, valdhor valdhorli...@... wrote: I haven't tried this so
Re: [flexcoders] Re: Updating renderer properties
Good point. So maybe I have to categorize everything as being data (in which case it hangs out with the data object) or style (in which case it would be applied to all the renderers and can be ran through the various style mechanisms). To be clear, the changes (that aren't data-dependent) being made to the renderers in my case can even be text and other such things which may not normally be thought of as styles but in reality it seems they actually are styles and could be treated as such. Thanks. Aaron On Thu, Jan 7, 2010 at 1:23 PM, turbo_vb timh...@aol.com wrote: One thought, since you're taking about a style, is to assign a styleName to the itemRenderer and update the backgroundColor style of the StyleDeclaration when the user changes the color. You may need to override the styleChanged() method the itemRenderer, to handle the update. -TH --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.com, Aaron Hardy aaronius...@... wrote: Hey folks. I have a renderer that needs information that is not based on the data object it's associated with. Essentially what I have is in View A of the app is a color selector. In View B, I have a tilelist with a custom renderer. All the renderers in the tile list display their data using the color that was selected in Part A. The way I see it, the color selected in Part A should be kept separate from the data object that gets injected into the item renderers. The color is just to make the data pretty in some way, it's not really data itself nor is it specific to an individual data object--it applies to all renderers in the list. This leads me to somehow keep the renderers updated with a separate color property. What's your preferred way of handling this scenario? Things I've thought of so far: (1) If I have an application-wide model (like in Cairngorm) I can set a color property there and either access it using the singleton accesor from within the renderer (cringe) or pass the model into the renderer using a class factory. Since the model instance shouldn't really ever change, I can then watch the model for changes to the color property. (2) Whenever the color changes, I can grab all the renderers for the given list and set their color property (cringe). Thoughts? Aaron
Re: [flexcoders] Re: Updating renderer properties
Yes, I suppose the line of what is or is not a style can be blurry at times. In any case, using transient properties inside a VO is what I was eluding in the first item of things I've thought of, the downside being that a model/VO of some type is needed in order to keep the renderer notified of updates to the property. In other words, I don't see a viable way of creating a foobar property inside the renderer and keeping it updated from an external source. Instead, the renderer would need access to a model that was set at instantiation through the renderer class factory. The renderer would then watch the model for changes to its foobar property. Aaron On Thu, Jan 7, 2010 at 2:58 PM, turbo_vb timh...@aol.com wrote: If it's a pure style, then yes that is a viable approach. However, if it's something like changing text (characters, not styles), then you might want to use [Transient] properties in a VO and/or use states in the itemRenderer. -TH --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.com, Aaron Hardy aaronius...@... wrote: Good point. So maybe I have to categorize everything as being data (in which case it hangs out with the data object) or style (in which case it would be applied to all the renderers and can be ran through the various style mechanisms). To be clear, the changes (that aren't data-dependent) being made to the renderers in my case can even be text and other such things which may not normally be thought of as styles but in reality it seems they actually are styles and could be treated as such. Thanks. Aaron On Thu, Jan 7, 2010 at 1:23 PM, turbo_vb timh...@... wrote: One thought, since you're taking about a style, is to assign a styleName to the itemRenderer and update the backgroundColor style of the StyleDeclaration when the user changes the color. You may need to override the styleChanged() method the itemRenderer, to handle the update. -TH --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.comflexcoders% 40yahoogroups.com, Aaron Hardy aaronius9er@ wrote: Hey folks. I have a renderer that needs information that is not based on the data object it's associated with. Essentially what I have is in View A of the app is a color selector. In View B, I have a tilelist with a custom renderer. All the renderers in the tile list display their data using the color that was selected in Part A. The way I see it, the color selected in Part A should be kept separate from the data object that gets injected into the item renderers. The color is just to make the data pretty in some way, it's not really data itself nor is it specific to an individual data object--it applies to all renderers in the list. This leads me to somehow keep the renderers updated with a separate color property. What's your preferred way of handling this scenario? Things I've thought of so far: (1) If I have an application-wide model (like in Cairngorm) I can set a color property there and either access it using the singleton accesor from within the renderer (cringe) or pass the model into the renderer using a class factory. Since the model instance shouldn't really ever change, I can then watch the model for changes to the color property. (2) Whenever the color changes, I can grab all the renderers for the given list and set their color property (cringe). Thoughts? Aaron
Re: [flexcoders] Re: Updating renderer properties
I think there might be a misunderstanding. If it's a transient property on the data objects that come through the data provider, I would have to change the property for all the objects in the data provider to be the same value since I want all the renderers to change in the same way. For example, let's say all my renderers say Woot: and then the data's text value. Then at runtime, the user, in a different part of the app, enters Niner into a text input and therefore I want all my renderers to now say Niner: and then the data's text value. In my case, the word Niner really has nothing to do with the data, it's almost more about the style of the renderers--or what the renderers look like around the actual data. If I were to use the transient property of the data provider objects, I'd have to loop through all of them and set the property's value to Niner. I'm not sure if that's what you were suggesting, but that seems dirtier to me than referencing a separate model from the renderers. I'm interested in understanding your analysis of this though even if we may disagree in the end. Aaron On Thu, Jan 7, 2010 at 5:13 PM, turbo_vb timh...@aol.com wrote: Sure, but you don't necessarily need a model to use a VO; it can just be the strongly typed object that the dataProvider uses for its items. If you then change the transient properties of that VO, the set data method of the itemRenderer will work out of the box; and you can then adjust the renderer. You're right in feeling dirty having an itemRenderer reference a model. But reacting to changes in the data is fine. IMHO. -TH --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.com, Aaron Hardy aaronius...@... wrote: Yes, I suppose the line of what is or is not a style can be blurry at times. In any case, using transient properties inside a VO is what I was eluding in the first item of things I've thought of, the downside being that a model/VO of some type is needed in order to keep the renderer notified of updates to the property. In other words, I don't see a viable way of creating a foobar property inside the renderer and keeping it updated from an external source. Instead, the renderer would need access to a model that was set at instantiation through the renderer class factory. The renderer would then watch the model for changes to its foobar property. Aaron On Thu, Jan 7, 2010 at 2:58 PM, turbo_vb timh...@... wrote: If it's a pure style, then yes that is a viable approach. However, if it's something like changing text (characters, not styles), then you might want to use [Transient] properties in a VO and/or use states in the itemRenderer. -TH --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.comflexcoders% 40yahoogroups.com, Aaron Hardy aaronius9er@ wrote: Good point. So maybe I have to categorize everything as being data (in which case it hangs out with the data object) or style (in which case it would be applied to all the renderers and can be ran through the various style mechanisms). To be clear, the changes (that aren't data-dependent) being made to the renderers in my case can even be text and other such things which may not normally be thought of as styles but in reality it seems they actually are styles and could be treated as such. Thanks. Aaron On Thu, Jan 7, 2010 at 1:23 PM, turbo_vb TimHoff@ wrote: One thought, since you're taking about a style, is to assign a styleName to the itemRenderer and update the backgroundColor style of the StyleDeclaration when the user changes the color. You may need to override the styleChanged() method the itemRenderer, to handle the update. -TH --- In flexcoders@yahoogroups.com flexcoders%40yahoogroups.comflexcoders% 40yahoogroups.comflexcoders% 40yahoogroups.com, Aaron Hardy aaronius9er@ wrote: Hey folks. I have a renderer that needs information that is not based on the data object it's associated with. Essentially what I have is in View A of the app is a color selector. In View B, I have a tilelist with a custom renderer. All the renderers in the tile list display their data using the color that was selected in Part A. The way I see it, the color selected in Part A should be kept separate from the data object that gets injected into the item renderers. The color is just to make the data pretty in some way, it's not really data itself nor is it specific to an individual data object--it applies to all renderers in the list. This leads me to somehow keep the renderers updated with a separate color property. What's your preferred way of handling this scenario? Things I've thought of so far: (1) If I have an application-wide