ok, new code, this time with IDs on dataProvider items for tracking. yes, i know there's no direct renderer-to-provider relationship. i now realize that the extra renderer instance is created for measurment (according to alex harui). but i'm still looking for an explanation on the multiple set data and commitProperties() calls.
i am curious, partly from a performance perspective, and partly because i want to understand how this works so i can slowly become better at architecting flex apps. code follows. StockApp.mxml ================================ <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="applicationCompleteListener(event)"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import mx.controls.HorizontalList; import mx.events.FlexEvent; import mx.core.ClassFactory; protected var list:HorizontalList; protected var provider:ArrayCollection; protected function applicationCompleteListener (e:FlexEvent):void { // Provider provider = new ArrayCollection(); provider.addItem({stockInfo:new StockInfo(), id:1}); // UI list = new HorizontalList(); list.width = 400; list.height = 100; list.dataProvider = provider; list.itemRenderer = new ClassFactory(StockInfoRenderer); addChild(list); } ]]> </mx:Script> </mx:Application> ================================ StockInfoRenderer.as ================================ package { import mx.containers.Canvas; import mx.controls.Button; public class StockInfoRenderer extends Canvas { protected var button:Button; public function StockInfoRenderer () { trace(""); trace("StockInfoRenderer CONSTRUCTOR CALLED."); } override protected function createChildren ():void { trace("StockInfoRenderer CREATE CHILDREN CALLED."); super.createChildren(); if (button == null) { button = new Button(); button.width = 100; } addChild(button); } override protected function commitProperties ():void { trace("StockInfoRenderer COMMIT PROPERTIES CALLED for ID: " + data.id); super.commitProperties(); button.label = data.stockInfo.getPrice(); } override public function set data (value:Object):void { super.data = value; trace("StockInfoRenderer SET DATA CALLED for ID: " + data.id); invalidateProperties() } } } ================================ StockInfo.as ================================ package { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.TimerEvent; import flash.utils.Timer; public class StockInfo extends EventDispatcher { private var t:Timer; public function StockInfo () { t = new Timer(1000); t.addEventListener(TimerEvent.TIMER, timerListener); t.start(); } public function timerListener (e:TimerEvent):void { dispatchEvent(new Event("UPDATE")); } public function getPrice ():Number { return Math.floor(Math.random()*1000)/100; } } } ================================ output ================================ StockInfoRenderer CONSTRUCTOR CALLED. StockInfoRenderer CREATE CHILDREN CALLED. StockInfoRenderer SET DATA CALLED for ID: 1 StockInfoRenderer COMMIT PROPERTIES CALLED for ID: 1 StockInfoRenderer SET DATA CALLED for ID: 1 StockInfoRenderer COMMIT PROPERTIES CALLED for ID: 1 StockInfoRenderer CONSTRUCTOR CALLED. StockInfoRenderer SET DATA CALLED for ID: 1 StockInfoRenderer CREATE CHILDREN CALLED. StockInfoRenderer COMMIT PROPERTIES CALLED for ID: 1 ================================ ~flexrookie --- In flexcoders@yahoogroups.com, "Tracy Spratt" <tspr...@...> wrote: > > Why do you think the renderer's commitProperties is being called more than > once for a single item? Your trace statements do not identify the item. > You understand that there is no direct relationship between the number of > items and the number of renderer instances? The number of instances depends > on the number of visible rows, plus a few for buffering. > > > > And are you just curious? The specific renderer instantiation behavior is > normally not of concern to a developer, but such concern sometimes > indicates misuse. > > > > Tracy > > > > _____ > > From: flexcoders@yahoogroups.com [mailto:flexcod...@yahoogroups.com] On > Behalf Of flexrookie > Sent: Saturday, February 28, 2009 9:35 PM > To: flexcoders@yahoogroups.com > Subject: [flexcoders] redundancy in custom ItemRenderer > > > > another question about ItemRenderers, using my previous stock example. > > i have noticed that my custom item renderer seems to be performing > redundant executions. for a single dataProvider item, i see two > renderer instances created. and for each instance, set data and > commitProperties() are called repeatedly. > > here's my code: > > StockApp.mxml > =================================== > <?xml version="1.0" encoding="utf-8"?> > <mx:Application xmlns:mx="http://www.adobe. <http://www.adobe.com/2006/mxml> > com/2006/mxml" > layout="absolute" > applicationComplete="applicationCompleteListener(event)"> > <mx:Script> > <![CDATA[ > import mx.collections.ArrayCollection; > import mx.controls.HorizontalList; > import mx.events.FlexEvent; > import mx.core.ClassFactory; > > protected var list:HorizontalList; > protected var provider:ArrayCollection; > > protected function applicationCompleteListener (e:FlexEvent):void { > // Provider > provider = new ArrayCollection(); > provider.addItem({stockInfo:new StockInfo()}); > > // UI > list = new HorizontalList(); > list.width = 400; > list.height = 100; > list.dataProvider = provider; > list.itemRenderer = new ClassFactory(StockInfoRenderer); > > addChild(list); > } > ]]> > </mx:Script> > </mx:Application> > =================================== > > StockInfoRenderer.as > =================================== > package { > import mx.containers.Canvas; > import mx.controls.Button; > > public class StockInfoRenderer extends Canvas { > protected var button:Button; > > public function StockInfoRenderer () { > trace("StockInfoRenderer CONSTRUCTOR CALLED."); > } > > override protected function createChildren ():void { > trace("StockInfoRenderer CREATE CHILDREN CALLED."); > super.createChildren(); > > if (button == null) { > button = new Button(); > button.width = 100; > } > addChild(button); > } > > override protected function commitProperties ():void { > trace("StockInfoRenderer COMMIT PROPERTIES CALLED."); > super.commitProperties(); > > button.label = data.stockInfo.getPrice(); > } > > override public function set data (value:Object):void { > trace("StockInfoRenderer SET DATA CALLED."); > super.data = value; > invalidateProperties() > } > } > } > =================================== > > OUTPUT: > =================================== > StockInfoRenderer CONSTRUCTOR CALLED. > StockInfoRenderer CREATE CHILDREN CALLED. > StockInfoRenderer SET DATA CALLED. > StockInfoRenderer COMMIT PROPERTIES CALLED. > StockInfoRenderer SET DATA CALLED. > StockInfoRenderer COMMIT PROPERTIES CALLED. > > StockInfoRenderer CONSTRUCTOR CALLED. > StockInfoRenderer SET DATA CALLED. > StockInfoRenderer CREATE CHILDREN CALLED. > StockInfoRenderer COMMIT PROPERTIES CALLED. > =================================== > > is the preceding redundancy typical, or am i doing something wrong? > > ~flashrookie >