5 Replies Latest reply on Dec 8, 2009 3:48 AM by iamfuric

    Synchronize XMLListCollection with underlying xml

    iamfuric Level 2

      Hello

      Consilder the following code:

       

      function test():void{

       

      var xml:XML=<root>

      <repository>

      <item label='1' type='one'/>

      <item label='2' type='one'/>

      </repository>

      </root>

       

      //case 1

           var collection:XMLListCollection = new XMLListCollection(xml...item.(@type=='one'));

           collection.addItem(<item id='3' label='3' type='one'/>) // xml now contains newly added item

      //case 2

           collection.source= (xml...item.(@type=='two')); //returns empty collections

           collection.addItem(<item label='3333' type='two'/>) // xml doesn't contain newly added item, but collection does.

      }

      So, my question is : how to propogate collection chages to underlying XML object in case 2 ?

       

      Note: collection narrowing and collection modification are DECOPLED in my application

       

      One of the solutions could be to return ObjectProxy(collection) with "change" listener and propogate changes to xml in listeners.

      Can anyone propose a better solution ?

       

      I also tried to add dummy item to XML if collection is empty, narrow collection once again  and remove previosly added dummy item, but still, later changes are not propogated to xml....

       

      Thanks

        • 2. Re: Synchronize XMLListCollection with underlying xml
          paul.williams Level 4

          Have you tried using a filterFunction to do your filtering?

          1 person found this helpful
          • 3. Re: Synchronize XMLListCollection with underlying xml
            iamfuric Level 2

            Thanks,Paul

            Now, if the item is added to filtered collection it also appears in xml model

             

             

            var model:XML=<root>

            <repository>

            <item label='1' type='one'/>

            <item label='2' type='one'/>

            </repository>

            </root>

            private function initialize():void{

            var collection:XMLListCollection = new XMLListCollection(model.repository.item);

            collection.filterFunction = function (item:Object):Boolean{

                      return "two"==item.@type;

            }

            collection.refresh();

            list.dataProvider =collection;

            }

            <DataGrid id='list'>

            ...

            </DataGrid>

             

             

            Another problem is, that data grid shows that newly added item  twice, I have to explicitly call refresh() on collection (dataProvider)  right after

            collection.appendChild(newItem)

            to fix it. Is this "designed behavior" or i'm missing something ?

            Thanks again for the help.

            • 4. Re: Synchronize XMLListCollection with underlying xml
              paul.williams Level 4

              Sounds more like a bug to me. If you post a standalone example I'll take a look.

              1 person found this helpful
              • 5. Re: Synchronize XMLListCollection with underlying xml
                iamfuric Level 2

                The problem seems to be in item update (not in add new  - another story).

                I'm attaching standalone example, try to add few items and edit id field : enter equal numbers, use "Enter" key.

                The behaivour is unpredictable .... sometimes label desappears, changes of one item applied  to the second with the same id...

                <?xml version="1.0" encoding="utf-8"?>
                <mx:Application
                
                 xmlns:mx="http://www.adobe.com/2006/mxml" 
                          initialize="init()" 
                
                >
                
                
                 
                 
                <mx:Script>
                     <![CDATA[
                
                import mx.controls.Alert;
                
                
                import mx.controls.List;
                
                import utils.XMLUtils;
                
                
                
                
                import mx.collections.XMLListCollection;
                
                
                          
                
                
                
                
                
                
                
                
                
                private function init():void{
                
                var collection:XMLListCollection = new XMLListCollection(model.item);
                               collection.filterFunction = 
                
                function (item:Object):Boolean{
                
                
                return "three"==item.@type;               }
                               collection.refresh();
                               list.dataProvider =collection;
                          }
                
                
                
                private var model:XML = <root>
                               <item id='1' type='one'/>
                               <item id='2' type='two'/>
                               </root>
                
                
                
                
                private function newItem():Object{
                
                
                return <item id='100' type='three'/>
                          }
                     ]]>
                
                </mx:Script>
                
                 
                
                <mx:ApplicationControlBar>
                
                
                <mx:Button click="{Alert.show(model.toXMLString())}" label="Show model"/>
                
                
                <mx:Button click="{(list.dataProvider as XMLListCollection).addItem(newItem())}" label="Add new item"/>
                
                
                <mx:Button click="{(list.dataProvider as XMLListCollection).refresh()}" label="refresh"/>
                
                
                </mx:ApplicationControlBar>
                
                
                
                 
                
                
                <mx:DataGrid
                
                  id="list" editable="true" >
                
                
                <mx:columns>
                
                
                <mx:DataGridColumn  dataField="@id" headerText="id" />
                
                
                <mx:DataGridColumn  dataField="@type" headerText="type"/>
                
                
                </mx:columns></mx:DataGrid>
                
                
                 
                 
                </mx:Application>