29 Replies Latest reply on Feb 7, 2011 11:59 AM by AlHolden-ut9CAY

    How to prevent deleted ghost data from returning to my datagrid?

    AlHolden Level 1

      I have a mx:DataGrid which is populated from an ArrayCollection - and has s:DropDownList and mx:Image types as custom item renderers within.

       

      When I delete a row via removeItemAt() - I follow up with validateNow() on the datagrid. All is well.

       

      The problem comes from adding a new row therafter. The custom item renderers on certain new rows will display data as if from the deleted item. But when I examine both the ArrayCollection and the DataGrid's dataprovider (via a breakpoint), there is nothing there to match what's being displayed in the row by the custom renderer. The data looks clean, but the renderer's "dirty".

       

      How do I delete a row (which contains custom item renderers) from a datagrid and insure that it stays dead (a subsequent new row creation does not contain these renderer relics)? I've tried validateNow(), invalidateList(), invalidateDisplayList(), even setting the dataprovider to null and back again.

       

      It's as though Flex 4 is dredging the actual renderer back from the dead, already set with g-g-g-g-ghost data!!

        • 1. Re: How to prevent deleted ghost data from returning to my datagrid?
          AlHolden Level 1

          I'm guessing that the answer lies in the fact that the renderers are being reused, and there's something amiss in an override of the data property?

          • 2. Re: How to prevent deleted ghost data from returning to my datagrid?
            Flex harUI Adobe Employee

            What does the code for your renderers look like?

            • 3. Re: How to prevent deleted ghost data from returning to my datagrid?
              AlHolden Level 1

              Below is the code for the s:DropDownList item renderer.

              I seem to recal as early as Flex 2 that one would have to provide an override of the set data function in order to prevent a scrolling bug, but this datagrid has never had to scroll (I've only populated 3 or 4 of the 18 visible slots).

              Is that relevant here? Do we still have to do something like "override public function set data(value:Object):void" in Flex 4 too?

              Thanks harUI

               

              <?xml version="1.0" encoding="utf-8"?>
              <s:MXDataGridItemRenderer
                  xmlns:fx="http://ns.adobe.com/mxml/2009"
                  xmlns:s="library://ns.adobe.com/flex/spark"
                  xmlns:mx="library://ns.adobe.com/flex/mx"
                  focusEnabled="true"
                  creationComplete="init()"
                  >
                 
                  <fx:Script>
                      <![CDATA[
                          public function init():void {
                              ddlComplex.selectedIndex = -1;
                              for (var i:int = 0; i< parentApplication.acComplexity.length; i++) {
                                  if (parentApplication.acComplexity[i].ComplexityTypeID == data.IssueComplexityTypeID) {
                                      ddlComplex.selectedIndex = i;
                                      break;
                                  }
                              }
                          }
                         
                          public function dropSkin():void {
                              ddlComplex.dropDown.width = 300;
                              ddlComplex.dropDown.height = 140;
                          }
                      ]]>
                  </fx:Script>

               

                  <s:HGroup horizontalAlign="center" width="100%">
                      <s:DropDownList id="ddlComplex" width="60" dataProvider="{parentApplication.acComplexity}" labelField="FlexDescrip" open="dropSkin()"/>
                  </s:HGroup>

               

              </s:MXDataGridItemRenderer>

              • 4. Re: How to prevent deleted ghost data from returning to my datagrid?
                Flex harUI Adobe Employee

                MXML based renderers can use the dataChange event.  It is not recommended to

                use creationComplete in a renderer as renderers get recycled.

                 

                See the item renderer posts on my blog

                 

                --

                Alex Harui

                Flex SDK Team

                Adobe System, Inc.

                http://blogs.adobe.com/aharui

                • 5. Re: How to prevent deleted ghost data from returning to my datagrid?
                  AlHolden Level 1

                  I suppose there must be more than simply replacing "creationComplete" with "dataChange" in my example, because that alone doesn't work.

                   

                  Changes to the DropDownList selection do not appear to update the arrayCollection like the generic grid renderers do; and I'm still unclear on whether or not I'm supposed to override the set data function as with prior Flex versions, and as your one-year old Checkbox example does.

                   

                  -- addendum --

                   

                  I dredged up some old code from an app I wrote in Flex 2.0.1 - and updated the Flex 4 renderer as shown below. This seems to work.

                   

                  I guess that - somewhere out there - I was fooled into thinking that we would no longer need to lovingly hand-code this extra stuff into all of our renderers any more.

                   

                  Thanks.

                   

                  <?xml version="1.0" encoding="utf-8"?>
                  <s:MXDataGridItemRenderer
                      xmlns:fx="http://ns.adobe.com/mxml/2009"
                      xmlns:s="library://ns.adobe.com/flex/spark"
                      xmlns:mx="library://ns.adobe.com/flex/mx"
                      focusEnabled="true"
                      dataChange="setData()"
                      >
                     
                      <fx:Script>
                          <![CDATA[
                              import spark.events.IndexChangeEvent;
                             
                              override public function set data(value:Object):void
                              {
                                  if(value != null)
                                  {
                                      super.data = value;
                                  }
                              }
                             
                              private function setData():void
                              {
                                  if(data != null)
                                  {
                                      for (var i:int = 0; i< parentApplication.acComplexity.length; i++) {
                                          if (parentApplication.acComplexity[i].ComplexityTypeID == data.IssueComplexityTypeID) {
                                              this.ddlComplex.selectedIndex = i;
                                              break;
                                          }
                                      }
                                  }
                              }
                             
                              public function dropSkin():void {
                                  ddlComplex.dropDown.width = 300;
                                  ddlComplex.dropDown.height = 140;
                              }
                             
                              public function userSelects(evt:IndexChangeEvent):void {
                                  data.IssueComplexityTypeID = evt.currentTarget.selectedItem.ComplexityTypeID;
                              }
                          ]]>
                      </fx:Script>

                   

                      <s:HGroup horizontalAlign="center" width="100%">
                          <s:DropDownList id="ddlComplex" width="60" change="userSelects(event)" dataProvider="{parentApplication.acComplexity}" labelField="FlexDescrip" open="dropSkin()"/>
                      </s:HGroup>

                   

                  </s:MXDataGridItemRenderer>

                   

                  Message was edited by: AlHolden

                  • 6. Re: How to prevent deleted ghost data from returning to my datagrid?
                    Flex harUI Adobe Employee

                    Overriding set data or using dataChange should be equivalent.

                     

                    To save changes from the dropdown selection, you will need to provide the

                    correct editorDataField with the proper data.

                    • 7. Re: How to prevent deleted ghost data from returning to my datagrid?
                      AlHolden Level 1

                      Sorry, my 2-1 post of success was in error. The above code does not work either.

                      Newly added rows will still contain a dropDown that's already set to the same selectedIndex of a previously deleted one.

                       

                      • Generate a new row via addItem
                      • Select a value from the itemRenderer dropdown within
                      • Delete this row via removeItemAt
                      • Generate another new row. The dropdown will be preselected to the ghost index of the deleted one.

                       

                      Whether I use the method I posted above, or if I use the one described in Flex 4's "Defining a property to return data" (editorDataField from your latest post)  makes no difference (and I'm guessing that your post really only applies to saving new changes anyway. That's really a separate issue from this one)

                       

                      I've even tried setting the value of the dataField in the arrayCollection to null just prior to removing it, in hopes that the dropdown would update and then have a "ghost selectedIndex" of -1 for the next time it was resused again.

                       

                      I'm trying to find an example somewhere of the correct way to do this: To use a s:DropDownList (or even  mx:ComboBox) as an item renderer for a mx:DataGrid, where the dropdown's dataProvider is an ArrayCollection obtained via RO call, and where the renderer does not contain selectIndex relics when reused again in a new row.

                       

                      Your blog does not contain any ComboBox or DropDownList example, and the Flex 4 help page only has an inline example - which skirts the whole issue of how to get the ArrayCollection in there from the parentApplication.

                      • 8. Re: How to prevent deleted ghost data from returning to my datagrid?
                        Flex harUI Adobe Employee

                        Check out some recent threads on MXDataGridItemRenderer.

                         

                        If that doesn't help, see if you can get a complete test case down to about

                        20-30 lines and post it.

                        • 9. Re: How to prevent deleted ghost data from returning to my datagrid?
                          AlHolden Level 1

                          Am I loosing my fricken mind here? You were talking about Adobe Forum "threads", right?

                           

                          • I enter "MXDataGridItemRenderer" in to the "Search Forums" box, and I get a list of Forums with numbers next to them. The link is just to the Forum home.
                          • When I try to "Search the Flex Forum" for "MXDataGridItemRenderer" then I get a list of 33 "results" with user names and no discussion title. The only clickable thing in these results just link right back to the Forum home again, well unless I want to see a blank user profile page.

                           

                          I'm really falling behind schedule here. Can somebody PLEASE just get me ONE url to a working example of a s:DropDownList itemRenderer in a mx:DataGrid that's powered by a RO ArrayCollection?

                           

                          I'm apparently too dumb to even search this site, it's amazing that I've even worked with Flex for the past 5 years without swamping this forum with other trivial questions, eh?

                          • 10. Re: How to prevent deleted ghost data from returning to my datagrid?
                            AlHolden Level 1

                            Using the Flex 4 help topic "Creating a Spark item editor for an MX DataGrid control" as a strict reference, the following does NOT work either.

                            Adding a new row will create a DownDownList with a default selectedIndex of one that was previously removed.

                             

                            Here is the renderer

                             

                            <?xml version="1.0"?>
                            <!-- itemRenderers\sparkmx\myComponents\NSEditor.mxml -->
                            <s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
                                                      xmlns:s="library://ns.adobe.com/flex/spark"
                                                      xmlns:mx="library://ns.adobe.com/flex/mx">
                               
                                <fx:Script>
                                    <![CDATA[
                                        import spark.events.IndexChangeEvent;

                             

                                        public var myRetVal:Object;
                                   
                                        public function dropSkin():void {
                                            ddlComplex.dropDown.width = 300;
                                            ddlComplex.dropDown.height = 140;
                                        }

                             

                                        public function userSelects(evt:IndexChangeEvent):void {
                                            myRetVal = evt.currentTarget.selectedItem;
                                        }
                                    ]]>
                                </fx:Script>
                               
                                <s:HGroup horizontalAlign="center" width="100%">
                                    <s:DropDownList id="ddlComplex" width="60" change="userSelects(event)" dataProvider="{parentApplication.acComplexity}" labelField="FlexDescrip" open="dropSkin()"/>
                                </s:HGroup>

                             

                            </s:MXDataGridItemRenderer>

                             

                            Here is the datagrid

                             

                            <mx:DataGrid height="100%" width="820" id="issuesGrid" editable="true" verticalAlign="top" x="10">

                             

                                <mx:columns>

                             

                                    <mx:DataGridColumn id="dgc1" width="40" editable="{isClaimUnlocked}" headerText="#" dataField="IssueNbr" textAlign="center"  resizable="false"/>

                             

                                    <mx:DataGridColumn id="dgc2" width="40" editable="{isClaimUnlocked}" headerText="COR?" dataField="isCorrection" itemRenderer="isCorrectionBox" rendererIsEditor="true" resizable="false"/>

                             

                                    <mx:DataGridColumn id="dgc3" editable="{isClaimUnlocked}" headerText="ISSUE NAME" dataField="IssueName" />

                             

                                    <mx:DataGridColumn id="dgc4" width="84" editable="{isClaimUnlocked}" headerText="COMPLEXITY" dataField="IssueComplexityTypeCode" editorDataField="myRetVal" itemRenderer="complexityCombo" rendererIsEditor="true"/>

                             

                                    <mx:DataGridColumn id="dgc5" width="80" editable="{isClaimUnlocked}" headerText="GUIDELINE" dataField="GuidelineHours">

                             

                                        <mx:itemEditor>

                             

                                            <fx:Component>

                             

                                                <mx:TextInput restrict="0-9." />

                             

                                            </fx:Component>

                             

                                        </mx:itemEditor>

                             

                                    </mx:DataGridColumn>

                             

                                    <mx:DataGridColumn id="dgc6" width="80" editable="true" visible="false" headerText="CLAIMED" dataField="claimed" textAlign="right">

                             

                                        <mx:itemEditor>

                             

                                            <fx:Component>

                             

                                                <mx:TextInput restrict="0-9." />

                             

                                            </fx:Component>

                             

                                        </mx:itemEditor>

                             

                                    </mx:DataGridColumn>

                             

                                    <mx:DataGridColumn id="dgc7" width="83" editable="true" headerText="RECOMMENDED" dataField="RecommendedHours" >

                             

                                        <mx:itemEditor>

                             

                                            <fx:Component>

                             

                                                <mx:TextInput restrict="0-9." />

                             

                                            </fx:Component>

                             

                                        </mx:itemEditor>

                             

                                    </mx:DataGridColumn>

                             

                                    <mx:DataGridColumn id="dgc8" width="72" headerText="PRIV NOTE" dataField="PrivateNotes" itemRenderer="noteButton.mxml.noteButton" rendererIsEditor="true" resizable="false"/>                      

                             

                                    <mx:DataGridColumn id="dgc9" width="72" headerText="AOC NOTE" dataField="NotesForAOC" itemRenderer="noteButton.mxml.noteButton" rendererIsEditor="true" resizable="false"/>

                             

                                </mx:columns>

                             

                            </mx:DataGrid>

                             

                            Here are the add and remove functions:

                             

                                        public function addIssue():void {
                                            var newIssue:Object = new Object();
                                            var newSequence:int = (acIssues.length+1);
                                            newIssue.IssueNbr = newSequence;
                                            newIssue.IssueName = 'new';
                                            newIssue.AppointmentID = AppointmentID;
                                            newIssue.ClaimHours = '';
                                            newIssue.ClaimID = ClaimID;
                                            newIssue.ClaimIssueID = 0;
                                            newIssue.GuidelineHours = newGuideline;
                                            newIssue.RecommendedHours = newGuideline;
                                            newIssue.isCorrection = '';
                                            newIssue.IssueComplexityTypeID = 0;
                                            newIssue.IssueTypeCode = IssueTypeCode
                                            newIssue.PrivateNotes = '';
                                            newIssue.NotesForAOC = '';
                                            acIssues.addItem(newIssue);
                                            issuesGrid.validateNow();
                                            issuesGrid.scrollToIndex(acIssues.length-1);
                                            issuesGrid.selectedIndex = acIssues.length-1;
                                        }
                                       
                                        public function removeIssue():void {
                                            var loc:int = issuesGrid.selectedIndex;
                                            acIssues.removeItemAt(loc);
                                            issuesGrid.validateNow();
                                            loc = loc-1;
                                            if (loc>=0) {
                                                issuesGrid.scrollToIndex(loc);
                                                issuesGrid.selectedIndex = loc;
                                            }
                                        }

                            • 11. Re: How to prevent deleted ghost data from returning to my datagrid?
                              Flex harUI Adobe Employee

                              I don't see any code that assigns the ddlComplex.selectedIndex or

                              selectedItem based on the MXDataGridItemRenderer's data property.

                              • 12. Re: How to prevent deleted ghost data from returning to my datagrid?
                                Flex harUI Adobe Employee

                                This thread is from another forum:

                                http://www.mail-archive.com/flexcoders@yahoogroups.com/msg137246.html//www.mail-archive.com/flexcoders@yahoogroups.com/msg137246.html

                                 

                                I didn't realize the search was so bad on the forum.  I usually use google.

                                • 13. Re: How to prevent deleted ghost data from returning to my datagrid?
                                  AlHolden Level 1

                                  Thank heavens you saw the same issue with your own search that I did. I thought I was going bonkers.

                                   

                                  I've determined that I am not tecnically capable of getting this renderer dropdownlist to use the selectedItem attribute. That seems to be what's causing the bulk of my issues. The example you cited uses the selectedIndex attribute, which seems to use a very handy relationship to the data itself, rather than anything I can find in data or dataGridListData to use as the attribute value. That's a convenience which escapes me.

                                   

                                  When I try to use a loop (or any other logic that's external to the literal tag) to locate the correct index on DataChange, that seems to be when all the other sympoms manifest: new rows apear to be pre-set with the indexes of deleted ones, and dropdowns revert to -1 the moment they loose focus. I suspect I'm casting the results of my search into the wrong type for an itemRenderer's selectedItem... I've tried strings and objects with no luck.

                                   

                                  So, I am left with the prospect of seeding the ArrayCollection with an extra column of integers representing the indices of each row. Off I go to the SQL and API which powers the RO and feeds the AC to this app. What a hack... I feel dirty.

                                  • 14. Re: How to prevent deleted ghost data from returning to my datagrid?
                                    AlHolden Level 1

                                    OK, I have taken your example from here:http://www.mail-archive.com/flexcoders@yahoogroups.com/msg137246//www.mail-archive.com/flexcoders@yahoogroups.com/msg137246

                                    and use it to demonstrate the issue.

                                    • Click Add
                                    • Change the name in the dropdown
                                    • Focus elsewhere and the dropdown might change itself. repeat
                                    • The dropdown might select the one you wanted the time before, or something else
                                    • Now select the row and delete it.
                                    • Click Add again. The brand new row will contain a dropdown with a selectedIndex of the deleted row, or something else

                                     

                                    Please let me know what's wrong. Thanks for all your help so far!

                                     

                                     

                                    Here is the base application testAlex.mxml:

                                     

                                    <?xml version="1.0" encoding="utf-8"?>

                                    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"

                                                   xmlns:s="library://ns.adobe.com/flex/spark"

                                                   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"

                                                   >

                                        <s:layout>

                                            <s:VerticalLayout horizontalAlign="center" paddingTop="10" gap="10"/>

                                        </s:layout>

                                     

                                        <fx:Script>

                                            <![CDATA[

                                                import mx.collections.ArrayCollection;

                                     

                                                [Bindable]

                                                protected var acPeople:ArrayCollection = new ArrayCollection(

                                                    [ { people_id: 1, people_name: 'Stephen', people_family:1},

                                                        { people_id: 2, people_name: 'Sheila', people_family:1},

                                                        { people_id: 3, people_name: 'David', people_family:1},

                                                        { people_id: 4, people_name: 'Ross', people_family:2},

                                                        { people_id: 5, people_name: 'Gareth', people_family:2},

                                                        { people_id: 6, people_name: 'Joyce', people_family:2}

                                                    ]);

                                     

                                                public function addPerson():void {

                                                    var newPerson:Object = new Object();

                                                    var newSequence:int = (acPeople.length+1);

                                                    newPerson.people_id = newSequence;

                                                    newPerson.people_name = 'new';

                                                    newPerson.people_family = -1;

                                                    acPeople.addItem(newPerson);

                                                    dgAlex.validateNow();

                                                    dgAlex.scrollToIndex(acPeople.length-1);

                                                    dgAlex.selectedIndex = acPeople.length-1;

                                                }

                                     

                                     

                                                public function removePerson():void {

                                                    var loc:int = dgAlex.selectedIndex;

                                                    acPeople.removeItemAt(loc);

                                                    dgAlex.validateNow();

                                                    loc = loc-1;

                                                    if (loc>=0) {

                                                        dgAlex.scrollToIndex(loc);

                                                        dgAlex.selectedIndex = loc;

                                                    }

                                                }

                                            ]]>

                                        </fx:Script>

                                     

                                        <fx:Declarations>

                                            <!-- Place non-visual elements (e.g., services, value objects) here -->

                                        </fx:Declarations>

                                     

                                        <s:Label text="People And Family Names" fontWeight="bold"/>

                                        <mx:DataGrid id="dgAlex" dataProvider="{acPeople}" rowCount="3" editable="true" height="400">

                                            <mx:columns>

                                                <mx:DataGridColumn headerText="Index" dataField="people_id" editable="false"/>

                                                <mx:DataGridColumn headerText="First Name" dataField="people_name"  editable="false"/>

                                                <mx:DataGridColumn headerText="Family Name" dataField="people_family" itemRenderer="render"

                                                     rendererIsEditor="true" editorDataField="selection"/>

                                            </mx:columns>

                                        </mx:DataGrid>

                                     

                                        <s:Button label="Add" click="addPerson()" />

                                        <s:Button label="Remove" click="removePerson()" />

                                    </s:Application>

                                     

                                     

                                    Here is renderer.mxml

                                     

                                    <?xml version="1.0" encoding="utf-8"?>
                                    <s:MXDataGridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
                                                              xmlns:s="library://ns.adobe.com/flex/spark"
                                                              xmlns:mx="library://ns.adobe.com/flex/mx"
                                                              focusEnabled="true"
                                                              dataChange="setData()"
                                                              >
                                      
                                        <fx:Script>
                                            <![CDATA[
                                                import mx.collections.ArrayCollection;
                                                import spark.events.IndexChangeEvent;
                                                public var selection:int;
                                               
                                                [Bindable]
                                                protected var acFamily:ArrayCollection = new ArrayCollection(
                                                    [ { family_id: 1, family_name:"Brown"},
                                                        { family_id: 2, family_name:"Owen"},
                                                        { family_id: 3, family_name:"Johnson"},
                                                        { family_id: 4, family_name:"Harding"},
                                                        { family_id: 5, family_name:"Manson"},
                                                        { family_id: 6, family_name:"Philips"},
                                                        { family_id: 7, family_name:"Hedge"}
                                                    ]);

                                     

                                                private function setData():void
                                                {
                                                    if(data != null)
                                                    {
                                                        for (var i:int = 0; i< acFamily.length; i++) {
                                                            if (acFamily[i].family_id == data.people_family) {
                                                                this.ddFamName.selectedItem = acFamily.getItemAt(i);
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                               
                                                protected function dropdownlist1_changeHandler(event:IndexChangeEvent):void
                                                {
                                                    selection = event.newIndex;
                                                }

                                     

                                                public function dropSkin():void {
                                                    ddFamName.dropDown.width = 100;
                                                    ddFamName.dropDown.height = 200;
                                                }

                                     

                                            ]]>
                                        </fx:Script>
                                       
                                        <s:DropDownList id="ddFamName" dataProvider="{acFamily}" labelField="family_name"
                                                        change="dropdownlist1_changeHandler(event)"
                                                        prompt="select" open="dropSkin()"
                                                        width="100%" top="2" bottom="2" left="2" right="2"/>
                                       
                                    </s:MXDataGridItemRenderer>

                                    • 15. Re: How to prevent deleted ghost data from returning to my datagrid?
                                      Flex harUI Adobe Employee

                                      Seems like you would be better off figuring out getting selectedItem to

                                      work.  It must be assigned an object in the DP, not a clone or copy of it.

                                      • 16. Re: How to prevent deleted ghost data from returning to my datagrid?
                                        AlHolden Level 1

                                        Gee. How helpful.

                                         

                                        This doesn't work, if that's even close to what you meant:

                                        ddFamName.selectedItem = ddFamName.dataProvider[i];

                                        • 17. Re: How to prevent deleted ghost data from returning to my datagrid?
                                          AlHolden Level 1

                                          nor does this:

                                          ddFamName.selectedItem = ddFamName.dataProvider.getItemAt(i);

                                          • 18. Re: How to prevent deleted ghost data from returning to my datagrid?
                                            AlHolden Level 1

                                            as not does this... neither:

                                            ddFamName.selectedItem = data[i];

                                            • 19. Re: How to prevent deleted ghost data from returning to my datagrid?
                                              AlHolden Level 1

                                              OK, that last one was a product of exasperation.

                                               

                                              But basically, I don't understand what it is that your suggesting I do.

                                               

                                              Here's an extract of setData() which also does not work:

                                                          private function setData():void
                                                          {
                                                              if(data != null)
                                                              {
                                                                  for (var i:int = 0; i< ddFamName.dataProvider.length; i++) {
                                                                      if (ddFamName.dataProvider[i].family_id == data.people_family) {
                                                                          ddFamName.selectedItem = ddFamName.dataProvider[i];
                                                                          break;
                                                                      }
                                                                  }
                                                              }
                                                          }

                                              • 20. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                Flex harUI Adobe Employee

                                                Another thing about Adobe forums:  When you post something, it doesn't show

                                                up in my mailbox for a while.  I was replying to your prior post where you

                                                said you were going to modify the DB.

                                                 

                                                Now that we have some actual code to work with, we be more specific:

                                                 

                                                The key principle remains assigning selectedItem to an element in the

                                                dataProvider.  This latest snippet might work better, but the original code

                                                seemed to fall victim to a binding code-gen trap:  If you make a var

                                                , the var's initialization becomes part of the binding code, so

                                                every time you access the var, you run the initializer again, which means

                                                that you have a whole new set of objects so they won't match (and it is

                                                inefficient).  I fixed that by assigning a static as the initializer:

                                                 

                                                           

                                                            protected var acFamily:ArrayCollection = staticAC;

                                                             

                                                            private static var staticAC:ArrayCollection = new

                                                ArrayCollection(

                                                                [ ,

                                                                    ,

                                                                    ,

                                                                    ,

                                                                    ,

                                                                    ,

                                                                     

                                                                ]);

                                                             

                                                 

                                                But I think the main problem was confusion about whether to use

                                                selectedIndex or family_id.  I changed the changeHandler like this:

                                                 

                                                            protected function

                                                dropdownlist1_changeHandler(event:IndexChangeEvent):void

                                                            {

                                                                selection = ddFamName.selectedItem.family_id;

                                                            }

                                                 

                                                In the original code it was assigning the selectedIndex, which does not

                                                match the family_id.

                                                 

                                                HTH

                                                • 21. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                  AlHolden Level 1

                                                  Thanks Alex

                                                  (In addition to the broken search & slow distribution, the Forum's wysiwyg editor is rather wonky too. Not sure if you intended the word Bindable to be a link to nowhere!)

                                                   

                                                  Your suggestions get us closer (in that the drop down list preserves the intended selection onFocusOut), but it still fails the test case I outlined in the bullet points above (and this very discussion's topic): Newly created rows will contain a drop down bearing the selectedIndex of a previously deleted one. g-g-g-g-ghost data!!

                                                   

                                                  Would you consider this to be a proper fix? I prefaced setData's decision loop with the ham-handed "selectedIndex = -1" as shown below:

                                                   

                                                              private function setData():void
                                                              {
                                                                 ddFamName.selectedIndex = -1;
                                                                  if(data != null)
                                                                  {
                                                                      for (var i:int = 0; i< ddFamName.dataProvider.length; i++) {
                                                                          if (ddFamName.dataProvider[i].family_id == data.people_family) {
                                                                              ddFamName.selectedItem = ddFamName.dataProvider[i];
                                                                              break;
                                                                          }
                                                                      }
                                                                  }
                                                              }

                                                   

                                                  Too forceful? Bad form?

                                                  • 22. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                    Flex harUI Adobe Employee

                                                    I think that is a classic coding problem.  If there isn't a match in the

                                                    loop, nothing is changed.  You can code it the way you suggested, but then

                                                    selection will be set twice when there is a match.

                                                     

                                                    I usually add a flag and set the flag if there is a match and check at the

                                                    end of the loop.

                                                    • 23. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                      AlHolden Level 1

                                                      (note that - because the above script change essentially "solves" the issue, what follows is a theroretical rant)

                                                       

                                                      But, aside from the secret internal workings of Flex, this is a brand new row in the grid.

                                                       

                                                      The people_family value in the AC - intended to inform that dropdown - was explicitly set to -1 by the addPerson() script.

                                                       

                                                      The dropdown (being reused - due to the secret internal workings of Flex) simply elected to ignore it.

                                                       

                                                      That's what I see as a lay-programmer.

                                                       

                                                      How should I otherwise add a row to what I thought was the dropdown's dataProvider, and have the dropdown respect it?

                                                       

                                                      P.S. Your job must require a bit of patience...

                                                      • 24. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                        Flex harUI Adobe Employee

                                                        I believe the oldest item renderer post on my blog emphasizes that renderers

                                                        get recycled and that every visual aspect must be determined from the data

                                                        object or associated data.  By not setting the dropdown to some selectedItem

                                                        when there is no match, you are not mapping every visual aspect of the

                                                        renderer to the data.

                                                         

                                                        People_family is not being mapped directly to selectedIndex in the example

                                                        you posted, it is only used to match against the dropdown's dataprovider.

                                                        • 25. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                          AlHolden Level 1

                                                          Understood, I am somewhat familiar with the concept of custom renderer reuse (what I referred to as the secret inner workings of Flex in my rant).

                                                          But consider the following:

                                                           

                                                          If you undo my latest fix and replace this line in addPerson()

                                                          newPerson.people_family = -1;

                                                           

                                                          with this:

                                                          newPerson.people_family = 4;

                                                           

                                                          Then the reused renderer has no problem understanding what I want. It creates a new row and matches the index properly.

                                                           

                                                          But even though I gave it a prompt attribute (which allows for -1 display) and specifically told it that I wanted -1 (just like I told it '4' above) it ignores and taunts me. I just want to slap it.

                                                           

                                                          Despite how you see it from the inside (I understand: -1 is not really any index at all); it just represents a puzzling duplicity of component behavior to me - and likely other developers as dumb as I - and certainly bumps your support volume I would think.

                                                          • 26. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                            Flex harUI Adobe Employee

                                                            I'm not sure what your code looks like now.  Someday I'll do a survey of the

                                                            5000+ posts on this forum and figure out what percentage contain a request

                                                            for more information.

                                                             

                                                            In the example I worked with, selectedItem is only set inside the for loop

                                                            if there is a match.  Since -1 is not in the dropdown DP, it won't match so

                                                            selectedItem will not be set and the dropdown will use whatever value it was

                                                            left at before it got recycled.

                                                             

                                                            The example I worked with was not setting the people_family as the

                                                            selectedIndex.

                                                             

                                                            And to me, that explains why -1 doesn't work and 4 did.

                                                            • 27. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                              AlHolden Level 1

                                                              Above (post 25), I was referring to the complete code set (from your url example) that I made available on 2-3 (post 14)

                                                               

                                                              This is the code that was "fixed" on 2-4 (post 21)

                                                               

                                                              Here, the addPerson() function sets the controlling variable to -1 when adding a new row to the AC which serves as the dropdown's DP, a dropdown which has a prompt attribute.

                                                               

                                                              I know you're busy, so I shouldn't bother you further with the perceived hypothetical bugs of a ranting lunatic (me).

                                                              • 28. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                                Flex harUI Adobe Employee

                                                                I think I'm lost. I can't tell if you are having an actual problem or not.

                                                                 

                                                                I added the ddFamName.selectedIndex = -1 to my copy of your test case and

                                                                when I hit add, it says select, not whatever it was when I deleted a row.

                                                                • 29. Re: How to prevent deleted ghost data from returning to my datagrid?
                                                                  AlHolden-ut9CAY

                                                                  Post 21 essentially closed this matter from your perspective (although in order to hit my deadline on time; my real fix was to rip out all new stuff - MXDataGridItemRenderer and DropDownList - and rebuild the whole thing with mx:ComboBox; using my old Flex 2 code as a model) although it does mean that the list is set twice purely as a corrective device. Something you pointed out.

                                                                   

                                                                  The posts which followed were just my attempts to demonstrate what I considered to be inconsistent behavior by DropDownList. But with the amount of support you need to provide - and the quantity of threads you probably have to juggle in your head - I shouldn't have expected you to follow along on my quixotic quest.

                                                                   

                                                                  Thanks for all your help.