Re: [flexcoders] Repeater not repeating
You could always extend ArrayCollection so that the extended-AC notifies its bound objects when its Array source changes. It depends whether you want the code change made to the 'source' of the data (in which case you'd update the AC, not the Array, as Tom mentioned), or the 'destination' (change the source Array on extended-AC). ___ Joseph Balderson, Flash Platform Developer | http://joeflash.ca Tom McNeer wrote: Jonathan, Thanks very much for your clear and thorough explanation. One of the major difficulties of discussing matters like this, of course, is semantics. Many common words we might use to describe apparent actions - like update or refresh -- have such specific meanings within the context of Flex -- often naming specific methods, in fact -- that someone like me, who is relatively new to Flex and ActionScript, may misspeak (and mislead) by referring to things incorrectly. I understand that the key concept is whether an object knows that something has happened. I mistakenly thought that the AC knew that its source had changed, but the Repeater didn't know that the AC had changed. You've straightened me out: the AC didn't know its source had changed, and therefore didn't communicate to any other object. The easiest solution is to use the AC directly to change the data. Thanks. I understand. I'll have to think about whether that's appropriate in this case, since a change in the source array would actually be generated by the addition of an object from a wholly different area of the app. But you've given me more understanding, and a good rule of thumb: when something doesn't appear to be updating, it probably hasn't been told to. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
Re: [flexcoders] Repeater not repeating
How would you do that, exactly? How could your extended ArrayCollection know the Array had changed? It's just not possible. On Fri, Jun 27, 2008 at 1:05 PM, Joseph Balderson [EMAIL PROTECTED] wrote: You could always extend ArrayCollection so that the extended-AC notifies its bound objects when its Array source changes. It depends whether you want the code change made to the 'source' of the data (in which case you'd update the AC, not the Array, as Tom mentioned), or the 'destination' (change the source Array on extended-AC). ___ Joseph Balderson, Flash Platform Developer | http://joeflash.ca Tom McNeer wrote: Jonathan, Thanks very much for your clear and thorough explanation. One of the major difficulties of discussing matters like this, of course, is semantics. Many common words we might use to describe apparent actions - like update or refresh -- have such specific meanings within the context of Flex -- often naming specific methods, in fact -- that someone like me, who is relatively new to Flex and ActionScript, may misspeak (and mislead) by referring to things incorrectly. I understand that the key concept is whether an object knows that something has happened. I mistakenly thought that the AC knew that its source had changed, but the Repeater didn't know that the AC had changed. You've straightened me out: the AC didn't know its source had changed, and therefore didn't communicate to any other object. The easiest solution is to use the AC directly to change the data. Thanks. I understand. I'll have to think about whether that's appropriate in this case, since a change in the source array would actually be generated by the addition of an object from a wholly different area of the app. But you've given me more understanding, and a good rule of thumb: when something doesn't appear to be updating, it probably hasn't been told to. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560 -- Flexcoders Mailing List FAQ: http://groups.yahoo.com/group/flexcoders/files/flexcodersFAQ.txt Search Archives: http://www.mail-archive.com/flexcoders%40yahoogroups.comYahoo! Groups Links
[flexcoders] Repeater not repeating
I need to have a repeater iterate over an array, displaying an instance of a custom component for each iteration. However, for testing, I am simply attempting to output a button with a static label within the repeater. Here's the basic code on the repeater: mx:ArrayCollection id=configAC source={estimate.configArray}/ mx:VBox width=100% id=configDisplay mx:Repeater dataProvider={configAC} id=configRepeater mx:Button label=D'oh / /mx:Repeater /mx:VBox Setting a breakpoint after the array is populated, I can see that: a) the original array (estimate.configArray) is populated with a single member, a custom ActionScript object. Length is 1, there is an object of the correct type at position 0. b) the array collection with the original array as source (configAC) shows the same contents. c) the dataprovider on the repeater, which is the array collection, shows the correction contents, an AC with a length of 1. d) the currentItem in the repeater shows the correct object from the AC. Yet the contents of the repeater, which should just be a simple button, do not display. I'm mystified. So I must be missing something simple. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
Re: [flexcoders] Repeater not repeating
Tom, It sounds like you are changing the contents of configArray? The ArrayCollection will not notice if you manipulate the underlying Array after the ArrayCollection has been created. You can either manipulate the ArrayCollection directly, or reset the source property on the ArrayCollection after you have changed the Array. Calling refresh() on the ArrayCollection does not fix the problem. For example, this works: mx:Application xmlns:mx=http://www.adobe.com/2006/mxml; layout=absolute mx:Script ![CDATA[ [Bindable] protected var a:Array = []; ]] /mx:Script mx:creationComplete ![CDATA[ a.push({a:one}); ac.source = ac.source; // reassign the source property to trigger a reset ]] /mx:creationComplete mx:ArrayCollection id=ac source={a}/ mx:DataGrid dataProvider={ac}/ /mx:Application -Jonathan http://jonathanbranam.net - Flex 3 Anatomy and Solutions On Thu, Jun 26, 2008 at 10:31 AM, Tom McNeer [EMAIL PROTECTED] wrote: I need to have a repeater iterate over an array, displaying an instance of a custom component for each iteration. However, for testing, I am simply attempting to output a button with a static label within the repeater. Here's the basic code on the repeater: mx:ArrayCollection id=configAC source={estimate.configArray}/ mx:VBox width=100% id=configDisplay mx:Repeater dataProvider={configAC} id=configRepeater mx:Button label=D'oh / /mx:Repeater /mx:VBox Setting a breakpoint after the array is populated, I can see that: a) the original array (estimate.configArray) is populated with a single member, a custom ActionScript object. Length is 1, there is an object of the correct type at position 0. b) the array collection with the original array as source (configAC) shows the same contents. c) the dataprovider on the repeater, which is the array collection, shows the correction contents, an AC with a length of 1. d) the currentItem in the repeater shows the correct object from the AC. Yet the contents of the repeater, which should just be a simple button, do not display. I'm mystified. So I must be missing something simple. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
Re: [flexcoders] Repeater not repeating
Jonathan, Thanks for the reply. The ArrayCollection will not notice if you manipulate the underlying Array after the ArrayCollection has been created Thanks. I understand that. But in debugging, I have confirmed that the ArrayCollection does contain the correct contents of the Array -- that the DataProvider in the Repeater also contains those contents -- and that the CurrentItem in the Repeater contains the correct contents. Could it be that the Repeater itself is not detecting the change from an empty AC to a populated one and not refreshing itself, even though its DataProvider is refreshed, because it's bound? Do I need to do something like call invalidateLayout() on the Repeater? -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
Re: [flexcoders] Repeater not repeating
Right. The data is there, that's not exactly the problem. The problem is that, although the data is there, the Repeater wasn't told that new data was available. It already looped through the data once when it was empty and it needs to be told that the data has changed. It listens to CollectionEvents and updates itself. Reassigning the source property is maybe the most accurate way to get the result, but it looks like calling refresh() on the ArrayCollection will trigger the Repeater to recreate its contents (FYI: This would NOT work for DataGrid). Repeater treats all CollectionEvents as equivalent except update which it ignores. As for currentItem, when you access that property the getter method will actually seek into the Collection if it hasn't been initialized yet, so accessing currentItem effectively sets the currentItem (and currentIndex) but it doesn't trigger creation of subcomponents. On Thu, Jun 26, 2008 at 11:48 AM, Tom McNeer [EMAIL PROTECTED] wrote: Jonathan, Thanks for the reply. The ArrayCollection will not notice if you manipulate the underlying Array after the ArrayCollection has been created Thanks. I understand that. But in debugging, I have confirmed that the ArrayCollection does contain the correct contents of the Array -- that the DataProvider in the Repeater also contains those contents -- and that the CurrentItem in the Repeater contains the correct contents. Could it be that the Repeater itself is not detecting the change from an empty AC to a populated one and not refreshing itself, even though its DataProvider is refreshed, because it's bound? Do I need to do something like call invalidateLayout() on the Repeater? -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
Re: [flexcoders] Repeater not repeating
First, Amy, thanks for your suggestion. I had already done this, although it wasn't clear from my note. Jonathan, Thanks for your explanation, and for the solution. Calling refresh() correctly alerts the Repeater. What I guess I don't understand is that the ArrayCollection was always correctly being updated -- I could see the values in the debugger. But even though the Collection was updated, it wasn't informing the Repeater. I assumed (obviously incorrectly) that if the source of the AC was updated, and the contents of the AC refreshed (as was happening), the AC would dispatch some event that would alert bound objects (in this case, the Repeater) of the change. Clearly, I have a lot to learn about the way events propagate from various changes. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
Re: [flexcoders] Repeater not repeating
Tom, Sure. It is confusing. I think the concept of the AC being updated and refreshed is the problem. I'd like to help you understand, because it will prevent future frustration! Your quote: I assumed (obviously incorrectly) that if the source of the AC was updated, and the contents of the AC refreshed (as was happening), the AC would dispatch some event that would alert bound objects (in this case, the Repeater) of the change. Specifically: contents of the AC refreshed (as was happening) The contents of the AC *is* the Array. So, when you change the Array, you are immediately changing the contents of the AC. There is no delay, no refresh, no update. It immediately changes and the AC immediately reflects those changes. If you do array.push(mydata) then ac.length it WILL be longer. And something like ac.getItemAt(ac.length-1) will immediately return mydata. Therefore, if you inspect the AC's source in the debugger it will always be up-to-date. The AC doesn't make a copy and it never has stale data. However, the AC itself does not know that its data has changed. If you call ac.addItem(mydate) then the AC knows that its data has changed. Only when the AC knows its data has changed does it dispatch any events. When you change the contents of the Array that the AC uses as source, it has no idea you've made any changes. Thus, any components using the AC are also not alerted to any changes. So, if a different event were to cause the component to loop through the AC again, it would see the new data. The trick is finding an event that does this reliably and repeatably. The easiest solution is to use the AC directly to change the data. Manipulating the AC will always update components that listen to events on the AC. On Thu, Jun 26, 2008 at 1:43 PM, Tom McNeer [EMAIL PROTECTED] wrote: First, Amy, thanks for your suggestion. I had already done this, although it wasn't clear from my note. Jonathan, Thanks for your explanation, and for the solution. Calling refresh() correctly alerts the Repeater. What I guess I don't understand is that the ArrayCollection was always correctly being updated -- I could see the values in the debugger. But even though the Collection was updated, it wasn't informing the Repeater. I assumed (obviously incorrectly) that if the source of the AC was updated, and the contents of the AC refreshed (as was happening), the AC would dispatch some event that would alert bound objects (in this case, the Repeater) of the change. Clearly, I have a lot to learn about the way events propagate from various changes. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
Re: [flexcoders] Repeater not repeating
Jonathan, Thanks very much for your clear and thorough explanation. One of the major difficulties of discussing matters like this, of course, is semantics. Many common words we might use to describe apparent actions - like update or refresh -- have such specific meanings within the context of Flex -- often naming specific methods, in fact -- that someone like me, who is relatively new to Flex and ActionScript, may misspeak (and mislead) by referring to things incorrectly. I understand that the key concept is whether an object knows that something has happened. I mistakenly thought that the AC knew that its source had changed, but the Repeater didn't know that the AC had changed. You've straightened me out: the AC didn't know its source had changed, and therefore didn't communicate to any other object. The easiest solution is to use the AC directly to change the data. Thanks. I understand. I'll have to think about whether that's appropriate in this case, since a change in the source array would actually be generated by the addition of an object from a wholly different area of the app. But you've given me more understanding, and a good rule of thumb: when something doesn't appear to be updating, it probably hasn't been told to. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560
RE: [flexcoders] Repeater not repeating
As Jonathan points out, if you use the ArrayCollection API to modify the AC, then the correct events are dispatched. If you use lower level api's, like directly assigning a property aarray.push. those events are not dispatched. Tracy From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On Behalf Of Jonathan Branam Sent: Thursday, June 26, 2008 2:15 PM To: flexcoders@yahoogroups.com Subject: Re: [flexcoders] Repeater not repeating Tom, Sure. It is confusing. I think the concept of the AC being updated and refreshed is the problem. I'd like to help you understand, because it will prevent future frustration! Your quote: I assumed (obviously incorrectly) that if the source of the AC was updated, and the contents of the AC refreshed (as was happening), the AC would dispatch some event that would alert bound objects (in this case, the Repeater) of the change. Specifically: contents of the AC refreshed (as was happening) The contents of the AC *is* the Array. So, when you change the Array, you are immediately changing the contents of the AC. There is no delay, no refresh, no update. It immediately changes and the AC immediately reflects those changes. If you do array.push(mydata) then ac.length it WILL be longer. And something like ac.getItemAt(ac.length-1) will immediately return mydata. Therefore, if you inspect the AC's source in the debugger it will always be up-to-date. The AC doesn't make a copy and it never has stale data. However, the AC itself does not know that its data has changed. If you call ac.addItem(mydate) then the AC knows that its data has changed. Only when the AC knows its data has changed does it dispatch any events. When you change the contents of the Array that the AC uses as source, it has no idea you've made any changes. Thus, any components using the AC are also not alerted to any changes. So, if a different event were to cause the component to loop through the AC again, it would see the new data. The trick is finding an event that does this reliably and repeatably. The easiest solution is to use the AC directly to change the data. Manipulating the AC will always update components that listen to events on the AC. On Thu, Jun 26, 2008 at 1:43 PM, Tom McNeer [EMAIL PROTECTED] mailto:[EMAIL PROTECTED] wrote: First, Amy, thanks for your suggestion. I had already done this, although it wasn't clear from my note. Jonathan, Thanks for your explanation, and for the solution. Calling refresh() correctly alerts the Repeater. What I guess I don't understand is that the ArrayCollection was always correctly being updated -- I could see the values in the debugger. But even though the Collection was updated, it wasn't informing the Repeater. I assumed (obviously incorrectly) that if the source of the AC was updated, and the contents of the AC refreshed (as was happening), the AC would dispatch some event that would alert bound objects (in this case, the Repeater) of the change. Clearly, I have a lot to learn about the way events propagate from various changes. -- Thanks, Tom Tom McNeer MediumCool http://www.mediumcool.com http://www.mediumcool.com 1735 Johnson Road NE Atlanta, GA 30306 404.589.0560