please tell me what invalidateList(); function does?
i have one line of code, in which this function is getting called on arraycollection object
like
dg.invalidateList();
where dg is the id of datagrid, dataprovider for this dg is colors which is an arraycollection??
plzz tell me wht the invalidateList() function is doin?
thanx
I would be willing to bet that whoever wrote that was trying to get the datagrid to refresh after the underlying arrayCollection was updated somehow. The better way of doing this is to dispatch a CollectionChange event on the arrayCollection after the update is made.
Example:
myArrayCollection.dispatchEvent( new CollectionEvent(CollectionEvent.COLLECTION_CHANGE) );
Refer to this StackOverflow debate:
what is the difference between invalidateList and invalidateDisplayList?
Seems to me everything was explained there :)
Ladislav
Related
I want to use event timer every 3 seconds to refresh List. I have created event timer but don't know about function to refresh List.
has anyone ever did this?
I'll appreciate your help, thanks
You should bind the List to a datasource (arrayCollection). Whenever the arrayCollection being updated, it will refresh the list automatically, example
<mx:List dataProvider="{myAC}"/>
where myAC is arrayCollection that can be changed to another arrayCollection.
Code samples, check on this line ( "section Binding to arrays" )
Take note that it's better to bind instead of doing something like
list.datasource = anotherArrayCollection;
i have a Flex tree control and im trying to select a tree node 3 levels down right after the dataProvider is assigned with a collection object like the following.
basically treeItem1, treeItem2, treeItem3 are the nodes in the tree and treeitem3 is a child of treeItem2 which is a child of treeItem1. Assume these treeItem(1,2,3) are referenced correctly from the collection items.
my problem is that if i wait for the whole component to load completely then select the nodes, it open/select/scrolltoIndex correctly. However, if i were to select the node right after the dataProvider is assigned, then it doesn't even open or select (basically the this.treeService.selectedItem is always null).
can anyone point out what i did wrong? is there anything needs to happen after the dataProvider is assigned?
thanks
this.treeService.dataProvider = oPricingHelper.getCurrentPricingSercicesTreeSource();
this.treeService.expandItem(treeItem1, true);
this.treeService.expandItem(treeItem2, true);
this.treeService.selectedItem = treeItem3;
this.treeService.scrollToIndex(this.treeService.selectedIndex);
I have used the updateComplete event to know when a component (such as a DataGroup or List) has completed rendering after performing a simple task (such as updating the dataProvider reference). Of course, you have to be careful and remove listening to updateComplete because it can run a lot, unless you have a need for it to run.
Something like:
//...some function...
this.treeService.addEventListener(FlexEvent.UPDATE_COMPLETE, onTreeUpdateComplete);
this.treeService.dataProvider = oPricingHelper.getCurrentPricingSercicesTreeSource();
//...rest of some function...
private function onTreeUpdateComplete(event:FlexEvent):void {
this.treeService.removeEventListener(FlexEvent.UPDATE_COMPLETE, onTreeUpdateComplete);
this.treeService.expandItem(treeItem1, true);
this.treeService.expandItem(treeItem2, true);
this.treeService.selectedItem = treeItem3;
this.treeService.scrollToIndex(this.treeService.selectedIndex);
}
I'm not positive your experiencing the same issue but I seem to have the same type of problem with using the advanced data grid, it appears in these cases where the dataprovider is acceptable as multiple types, the components do some extra work in the background to wrap things up into something Hierarchical (HierarchicalData or HierarchicalCollectionView) and in doing so the dataprovider setter call is not synchronous (so it will return before actually having assigned the internal property storing the dataprovider). I've used callLater in this case with moderate success, callLater is generally a bad practice but basically adds a function to a list of functions to call once background processing is done, so this is assuming that something in the dataprovider setter called UIComponent.suspendBackgroundProcessing() and that it will subsequently call UIComponent.resumeBackgroundProcessing() and then it will execute the list of functions added by using callLater. Alternatively you could use setTimeout(someFunction,1000).
These are both "hacks" the real solution is to dig into the framework code and see what it's really doing when you tell it to set the dataprovider. Wherever you see that it actually has set the dataprovider you could extend that class and dispatch an event that you could listen for to run the function to do the selections after this point.
If anyone has a better solution please by all means correct me (I would love to have a better answer than this)
The help page on the BindUtils.bindProperty function:
http://livedocs.adobe.com/flex/3/langref/mx/binding/utils/BindingUtils.html
Has this to say:
"For example, to bind the property host.a.b.c, call the method as: bindProperty(host, ["a","b","c"], ...)."
But what if I need to bind to host.a.b[2].c? How do I do that?
There are often binding issues when you drill down into objects, at least under most normal binding sitautions.
Not sure if this is what you're after, but:
[Bindable] public var myObject = a.b[2];
And later in your code:
<myComp myValue="{myObject.c}" />
However, I would consider it highly unusual to bind to a specific element of an array. If you could expand on what you're trying to do; maybe we can point you in a different direction.
It turns out, flex lets me do this:
bindProperty(host, ["a","b","2","c"], ...);
Hazzah!
I'm working on a Flex 3 project, and I'm using a pair of XMLListCollection(s) to manage a combobox and a data grid.
The combobox piece is working perfectly. The XMLListCollection for this is static. The user picks an item, and, on "change", it fires off an addItem() to the second collection. The second collection's datagrid then displays the updated list, and all is well.
The datagrid, however, is editable. A further complication is that I have another event handler bound to the second XMLLIstCollection's "change" event, and in that handler, I do make additional changes to the second list. This essentially causes an infinite loop (a stack overflow :D ), of the second lists "change" handler.
I'm not really sure how to handle this. Searching has brought up an idea or two regarding AutoUpdate functionality, but I wasn't able to get much out of them. In particular, the behavior persists, executing the 'updates' as soon as I re-enable, so I imagine I may be doing it wrong. I want the update to run, in general, just not DURING that code block.
Thanks for your help!
Trying to bind the behaviour to a custom event rather than the CHANGE event.
I.e. do what you are doing now, but dispatch and handle a custom event to do the work.
Have you considered using callLater?
Does direct manipulation of XMLListCollection's source XMLList have the same results?
Have you considered something like:
private function changeHandler( event:Event ):void
{
event.target.removeEventListener( event.type, changeHandler );
// your code here.
event.target.addEventListener( event.type, changeHandler );
}
I'm having some issues when calling getItemIndex on an ArrayCollection with a filterFunction set.
I do something like myAC.removeItemAt(myAC.getItemIndex(myObject)), which works fine when the filtering hasn't been applied. As soon as filtering is applied, getItemIndex seems to return -1 in every case.
Has anyone come across this before? What the best way to remove an item form a filtered ArrayCollection?
Thanks a lot.
Evan
What exactly is your filter filtering out? If you've filtered out everything, getItemIndex should return -1.
Are you hoping to remove items that are still visible when your filter has been applied? If you still want to remove an item that's filtered out, you could temporarily disable the filter:
var filter:Function = ac.filterFunction;
ac.fiterFunction = null;
ac.refresh();
// remove item
ac.filterFunction = filter;
ac.refresh();
I think you'll find there is a source object within the ArrayCollection. What you are seeing is a view of the underlying data with a sort or filter applied. You really want to delete from the underlying source object.
Any time I've dealt with adding and removing items from ArrayCollections in Flex, I've always kept a copy of the original ArrayCollection. Any adding or removing of items happen to that original copy.
Once the changes have been made to the original, I move those forward to the filtered list.
Remove it from source directly
arrayCollection.source.splice(i, 1)
Yeah, so I did find out that I was changing the property of the object - to one that would have it filtered out - prior to trying to remove it. Of course I would get -1 in that case. My mistake.
Ended up going with your suggestion, Stiggler. Seems to work fine, though it seems like there should be a less hackish way to handle this type of thing. Perhaps a parameter you could pass to removeItemAt that would let you access the unfiltered collection.
Anyway, thanks to both of you for your responses. Much appreciated.