8 Replies Latest reply on Aug 23, 2007 7:23 AM by Megha_Shah

    Edit filtered ArrayCollection messes up Datagrid

    scabbage Level 1
      I understand Datagrid + itemrenderer is a frustrating issue sometimes. After Googling around, I got no luck solving my problem. It goes like this:

      I have an ArrayCollection objectArray as the dataprovider for a datagrid. I applied a filtered function on objectArray and the datagrid displayed the filtered array with no problem. However, when I looped through the filtered array and made some changes, the datagrid went crazy. The order got changed and some of the changed values didn't show up as changed.

      Did anyone come across the same issue? Can anyone give me some idea of what's going on?

      Thanks.
        • 1. Re: Edit filtered ArrayCollection messes up Datagrid
          Level 7
          I got that problem before, becareful when you are updating the Array.
          Sometimes for me the data disapear also and I fixed with refres method.
          MyArray.refresh();
          Rgds

          JFB

          "scabbage" <webforumsuser@macromedia.com> wrote in message
          news:f9mc4q$an2$1@forums.macromedia.com...
          >I understand Datagrid + itemrenderer is a frustrating issue sometimes.
          >After
          > Googling around, I got no luck solving my problem. It goes like this:
          >
          > I have an ArrayCollection objectArray as the dataprovider for a
          > datagrid. I applied a filtered function on objectArray and the
          > datagrid
          > displayed the filtered array with no problem. However, when I looped
          > through
          > the filtered array and made some changes, the datagrid went crazy. The
          > order
          > got changed and some of the changed values didn't show up as changed.
          >
          > Did anyone come across the same issue? Can anyone give me some idea of
          > what's
          > going on?
          >
          > Thanks.
          >


          • 2. Re: Edit filtered ArrayCollection messes up Datagrid
            scabbage Level 1
            JFB,

            I followed what you said and did a myArray.refresh() after I changed all my myArray.someProperty from false to true (myArray is the filtered array). However, in the Datagrid, the someProperty column didn't show "true" everywhere, but with true and false alternating (false, true, false, true, false...) across the datagrid. Any idea how this coud be solved?

            Thanks.
            • 3. Re: Edit filtered ArrayCollection messes up Datagrid
              Level 7
              Sorry.. I can't help you without see some code.
              Rgds

              JFB


              "scabbage" <webforumsuser@macromedia.com> wrote in message
              news:f9o651$dsb$1@forums.macromedia.com...
              > JFB,
              >
              > I followed what you said and did a myArray.refresh() after I changed all
              > my
              > myArray.someProperty from false to true (myArray is the filtered array).
              > However, in the Datagrid, the someProperty column didn't show "true"
              > everywhere, but with true and false alternating (false, true, false, true,
              > false...) across the datagrid. Any idea how this coud be solved?
              >
              > Thanks.
              >


              • 4. Re: Edit filtered ArrayCollection messes up Datagrid
                scabbage Level 1
                Ok, I think I found where the problem is. My code looks like this:

                ------------------------------------------------------------------------------------------
                <mx:Script>
                <![CDATA[

                private function applyFilter():void {
                myArray.filterFunction = myFilter;
                myArray.refresh();
                }

                private function changeValue():void {
                for each (var item:Item in myArray) {
                item.value = true;
                }
                myArray.refresh();
                }


                // simple filter
                private function myFilter(item:Object):void {
                if (item.id > 5 && item.id < 20)
                return true;
                else
                return false;
                }

                ]]>
                </mx:Script>

                <mx:DataGrid dataProvider="{myArray}"/>
                <mx:Button label="filter" click="applyFilter()"/>
                <mx:Button label="change value" click="changeValue()"/>

                ------------------------------------------------------------------------------------------ ---------------

                So what causes the problem is the "changeValue" function. Solution to my problem: bring "myArray.refresh()" inside the loop. So instead of doing a refresh after all the values are changed, refresh the array EVERY TIME you change a value. I realized that without doing this, the "for each" loop doesn't loop through the filtered array correctly. Some items gets accessed twice and some don't get accessed at all. This explains the "true, false, true, false, ..." alternating result I got previously.

                However, I was not able to reproduce this problem using a 5000-item toy ArrayCollection (different objects). Flex made the right value changes with only one array refresh at the end.


                quote:

                Originally posted by: Newsgroup User
                Sorry.. I can't help you without see some code.
                Rgds

                JFB


                "scabbage" <webforumsuser@macromedia.com> wrote in message
                news:f9o651$dsb$1@forums.macromedia.com...
                > JFB,
                >
                > I followed what you said and did a myArray.refresh() after I changed all
                > my
                > myArray.someProperty from false to true (myArray is the filtered array).
                > However, in the Datagrid, the someProperty column didn't show "true"
                > everywhere, but with true and false alternating (false, true, false, true,
                > false...) across the datagrid. Any idea how this coud be solved?
                >
                > Thanks.
                >





                • 5. Re: Edit filtered ArrayCollection messes up Datagrid
                  Level 7
                  mmm...
                  Filter should be working, lets try to change Item for object.

                  private function changeValue():void {
                  for each (var item:Object in myArray) {
                  item.value = true;
                  }
                  myArray.refresh();
                  }


                  "scabbage" <webforumsuser@macromedia.com> wrote in message
                  news:f9p2jh$dua$1@forums.macromedia.com...
                  > Ok, I think I found where the problem is. My code looks like this:
                  >
                  >
                  > --------------------------------------------------------------------------------
                  > ----------
                  > <mx:Script>
                  > <![CDATA[
                  >
                  > private function applyFilter():void {
                  > myArray.filterFunction = myFilter;
                  > myArray.refresh();
                  > }
                  >
                  > private function changeValue():void {
                  > for each (var item:Item in myArray) {
                  > item.value = true;
                  > }
                  > myArray.refresh();
                  > }
                  >
                  >
                  > // simple filter
                  > private function myFilter(item:Object):void {
                  > if (item.id > 5 && item.id < 20)
                  > return true;
                  > else
                  > return false;
                  > }
                  >
                  > ]]>
                  > </mx:Script>
                  >
                  > <mx:DataGrid dataProvider="{myArray}"/>
                  > <mx:Button label="filter" click="applyFilter()"/>
                  > <mx:Button label="change value" click="changeValue()"/>
                  >
                  >
                  > --------------------------------------------------------------------------------
                  > -------------------------
                  >
                  > So what causes the problem is the "changeValue" function. Solution to my
                  > problem: bring "myArray.refresh()" inside the loop. So instead of doing a
                  > refresh after all the values are changed, refresh the array EVERY TIME you
                  > change a value. I realized that without doing this, the "for each" loop
                  > doesn't
                  > loop through the filtered array correctly. Some items gets accessed twice
                  > and
                  > some don't get accessed at all. This explains the "true, false, true,
                  > false,
                  > ..." alternating result I got previously.
                  >
                  > However, I was not able to reproduce this problem using a 5000-item toy
                  > ArrayCollection (different objects). Flex made the right value changes
                  > with
                  > only one array refresh at the end.
                  >
                  >
                  >
                  quote:

                  Originally posted by: Newsgroup User
                  > Sorry.. I can't help you without see some code.
                  > Rgds
                  >
                  > JFB
                  >
                  >
                  > "scabbage" <webforumsuser@macromedia.com> wrote in message
                  > news:f9o651$dsb$1@forums.macromedia.com...
                  > > JFB,
                  > >
                  > > I followed what you said and did a myArray.refresh() after I changed all
                  > > my
                  > > myArray.someProperty from false to true (myArray is the filtered array).
                  > > However, in the Datagrid, the someProperty column didn't show "true"
                  > > everywhere, but with true and false alternating (false, true, false,
                  > > true,
                  > > false...) across the datagrid. Any idea how this coud be solved?
                  > >
                  > > Thanks.
                  > >
                  >
                  >
                  >

                  >
                  >
                  >


                  • 6. Re: Edit filtered ArrayCollection messes up Datagrid
                    scabbage Level 1
                    Changing from Item to Object didn't help.
                    • 7. Re: Edit filtered ArrayCollection messes up Datagrid
                      scabbage Level 1
                      Sorry when I said I found the solution. Refreshing the arraycollection in the loop is very inefficient and unnecessary. The actual problem is using "for each" loop over an arraycollection. "for each" is not designed for arraycollections. It's for Arrays. So a simple solution here is to change the "changeValue()" function to:

                      -----------------
                      private function changeValue():void {
                      for each (var item:Item in myArray.toArray()) {
                      item.value = true;
                      }
                      }
                      ----------------------

                      No need to do refresh of the arrayCollection at all and everything works.
                      • 8. Re: Edit filtered ArrayCollection messes up Datagrid
                        Megha_Shah
                        Hi,

                        You call the changeValue function on button click and edit the array.And again you refresh the array.
                        But when you refresh the array it calls its filter function automatically,So it gives u filtered data.I think you don't refresh the
                        array after change it.

                        private function changeValue():void {
                        for each (var item:Item in myArray) {
                        item.value = true;
                        }
                        //no need to refresh
                        //myArray.refresh();
                        }

                        I hope it will help you.

                        Thanks,
                        Megha