My bad (at least in this example). The selectedItems getter is incorrect. On Tue, May 18, 2010 at 12:15 PM, Richard Rodseth <rrods...@gmail.com>wrote:
> I've attempted to create a one-file test case, and while it doesn't exhibit > the script timeout, the selection restoration does not work as part of the > collection listener. > Is it significant that "selectedItems" does not show up in code completion > while selectedIndices does? > > <?xml version="1.0" encoding="utf-8"?> > <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" > layout="vertical" minWidth="955" minHeight="600" > > creationComplete="application1_creationCompleteHandler(event)" > > > > <mx:Script> > <![CDATA[ > import mx.collections.ArrayCollection; > import mx.events.CollectionEvent; > import mx.events.CollectionEventKind; > import mx.events.FlexEvent; > import mx.events.ListEvent; > > > [Bindable] > public var items:ArrayCollection = new ArrayCollection(); > > [Bindable(event="selectionChanged")] > public function get selectedItems():Array { > return _selectedItems; > } > > private var _selectedItems:Array = []; > private var _selectedIds:Array = []; > > private function selectItems(items:Array):void { > _selectedItems = items; > _selectedIds = this.toIds(items); > > dispatchEvent(new Event("selectionChanged")); > } > > protected function > application1_creationCompleteHandler(event:FlexEvent):void > { > items.addEventListener(CollectionEvent.COLLECTION_CHANGE, > itemsListener, false, 0, true); > } > > private function itemsListener(event:CollectionEvent):void { > if (event.kind == CollectionEventKind.RESET) { > this.restoreSelection(); > } > } > > private function refresh():void { > > this.items.source = [ { uid:"1", name:"Root", children: [ { > uid:"2", name:"Child" } ] } ]; > > } > > private function toIds(items:Array):Array { > var result:Array = new Array(); > for each (var item:Object in items) { > result.push(item.uid); > } > return result; > } > > private function toItems(ids:Array):Array { > var root:Object = this.items ? this.items.getItemAt(0) : > null; > > var result:Array = new Array(); > for each (var id:String in ids) { > var item:Object = find(root, id); > if (item) { > result.push(item); > } > } > return result; > } > > private function restoreSelection():void { > _selectedItems = toItems(_selectedIds); > dispatchEvent(new Event("selectionChanged")); > > } > > private function find(start:Object, uid:String):Object { > if (start.uid == uid) > return start; > for each (var child:Object in start.children) { > var found:Object = this.find(child, uid); > if (found) > return found; > } > return null; > } > > > protected function tree1_changeHandler(event:ListEvent):void > { > this.selectItems(theTree.selectedItems); > } > > protected function button1_clickHandler(event:MouseEvent):void > { > this.refresh(); > } > > > > ]]> > </mx:Script> > > > <mx:Tree id="theTree" > dataProvider="{this.items}" > selectedItems="{this.selectedItems}" > labelField="name" > allowMultipleSelection="true" > change="tree1_changeHandler(event)"/> > > <mx:Button label="Refresh" click="refresh()"/> > <mx:Button label="Restore Selection" click="restoreSelection()"/> > > > </mx:Application> > > > > On Tue, May 18, 2010 at 9:23 AM, Richard Rodseth <rrods...@gmail.com>wrote: > >> That sounds about right. moveNext() does appear in the stack sometimes, >> and I am changing the data provider contents. >> I may have to put the "restoreselection" code somewhere other than in a >> collection change handler. >> >> >> >> >> On Tue, May 18, 2010 at 9:16 AM, Alex Harui <aha...@adobe.com> wrote: >> >>> >>> >>> If that’s true, on the second invocation, step through it. It might be >>> hung up in moveNext() not advancing to the next item, maybe because you’ve >>> run out of items. >>> >>> >>> >>> On 5/17/10 11:12 PM, "Richard Rodseth" <rrods...@gmail.com> wrote: >>> >>> >>> >>> >>> >>> >>> I think I already mentioned it was called twice. I can double-check >>> tomorrow. >>> >>> On Mon, May 17, 2010 at 9:35 PM, Alex Harui <aha...@adobe.com> wrote: >>> >>> >>> >>> >>> >>> >>> Set a breakpoint on setSelectionDataLoop. See how often it gets called. >>> >>> >>> >>> On 5/17/10 4:49 PM, "Richard Rodseth" <rrods...@gmail.com < >>> http://rrods...@gmail.com> > wrote: >>> >>> >>> >>> >>> >>> >>> Thanks for trying. No, the presentation model has an array collection >>> whose .source gets changed after an HTTPService call returns (although I >>> should mention that I am using my mock service layer at the moment). I added >>> a a collection change listener to the collection reference. >>> I have set a breakpoint in setSelectionDataLoop(). I hit it twice (the >>> parameters appear the same - index 0, items array containing the object to >>> select, useFind=false). Then the debugger stopped with the finally{} block >>> in Binding.watcherFired highlighted and the stack crawl below. Below this >>> stack crawl I've included the last few lines of the one that shows up in the >>> console. >>> >>> Main Thread (Suspended: Error: Error #1502: A script has executed for >>> longer than the default timeout period of 15 seconds.) >>> mx.binding::Binding/watcherFired >>> mx.binding::Watcher/notifyListeners >>> mx.binding::PropertyWatcher/eventHandler >>> flash.events::EventDispatcher/dispatchEventFunction [no source] >>> flash.events::EventDispatcher/dispatchEvent [no source] >>> >>> com.companyname.admin.deviceshome.ui.presentation::DevicesHome/changeSelectedGroupIds >>> >>> >>> com.companyname.admin.deviceshome.ui.presentation::DevicesHome/groupsChangedListener >>> >>> flash.events::EventDispatcher/dispatchEventFunction [no source] >>> flash.events::EventDispatcher/dispatchEvent [no source] >>> mx.collections::ListCollectionView/dispatchEvent >>> mx.collections::ListCollectionView/ >>> http://www.adobe.com/2006/flex/mx/internal::reset >>> mx.collections::ListCollectionView/set list >>> mx.collections::ArrayCollection/set source >>> <anonymous> >>> mx.rpc::Responder/result >>> <anonymous> >>> Array$/_forEach [no source] >>> Array/http://adobe.com/AS3/2006/builtin::forEach [no source] >>> <anonymous> >>> flash.utils::Timer/_timerDispatch [no source] >>> flash.utils::Timer/tick [no source] >>> >>> Console: >>> >>> Error: Error #1502: A script has executed for longer than the default >>> timeout period of 15 seconds. >>> at mx.controls.treeClasses::HierarchicalViewCursor/moveNext() >>> at >>> mx.controls.listClasses::ListBase/setSelectionDataLoop()[C:\autobuild\3.5.0\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:6455] >>> >>> >>> On Mon, May 17, 2010 at 4:09 PM, Oleg Sivokon <olegsivo...@gmail.com < >>> http://olegsivo...@gmail.com> > wrote: >>> >>> >>> >>> >>> >>> >>> I wish I could help more... well here's another guess: >>> - if you are using XML / XMLList, and have used insertBefore / isertAfter >>> from the same XML / XMLList, then it is a known bug. >>> - if you dispatch "collectionChange" on your own you might have messed >>> something in the event's properties, which then will make the collection run >>> in a loop thinking it's being updated over and over again. It is slow, but >>> it isn't that slow to run out of script timeout limit :) >>> Anyways, bindings are the first suspect in such case, but if that's >>> not... ah, and, why won't you debug it? the debugger should be able to look >>> into the framework sources. If, for whatever reason it doesn't, copy the >>> Tree and other classes involved into your project and try debugging this >>> way. >>> >>> Best. >>> >>> Oleg >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> -- >>> Alex Harui >>> Flex SDK Team >>> Adobe System, Inc. >>> http://blogs.adobe.com/aharui >>> >>> >> >> >