6 Replies Latest reply on Feb 9, 2010 2:09 PM by John Hall

    Binding principles question

    John Hall Level 4

      I have an app for sports scheduling that has divisions, teams, people, etc

       

      For the teams, I allow users to drag and drop persons from a list populated with all persons and then I put that person inside teams.players arrayCollection. Now when I go back to the people form and update the original data, the "choose from" list updates fine but the display of current players in another list box that relies upon teams.players arraycollection does not reflect that the changes made to object inside that ac.

       

      Hope that makes sense.

       

      I can solve the problem by iterating over all the players and updating information within the teams arrayCollection, but I get the sense that I'm missing a basic principle of binding if I have to do that. Am I missing something obvious?

        • 1. Re: Binding principles question
          archemedia Level 4

          If your drag drop operation is basic, just use the build in mechanisms. Here is a simple example.

          The dataProviders of both lists will be updated automatically:

           

          <?xml version="1.0" encoding="utf-8"?>
          <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" creationComplete="init()">
             
              <mx:Script>
                  <![CDATA[
                      import mx.events.DragEvent;
                      import mx.collections.ArrayCollection;
                     
                      [Bindable]
                      private var allPlayers:ArrayCollection = new ArrayCollection();
                      [Bindable]
                      private var selectedPlayers:ArrayCollection = new ArrayCollection();
                     
                      private function init():void
                      {
                          var apa:Array = [
                              {id: 1, name: "Pele"},
                              {id: 1, name: "Maradona"},
                              {id: 1, name: "Platini"},
                              {id: 1, name: "The Pope"}];
                          allPlayers.source = apa;
                      }
                     
                  ]]>
              </mx:Script>
             
              <mx:List dataProvider="{allPlayers}" dragEnabled="true" labelField="name" dragMoveEnabled="true"/>
              <mx:List dataProvider="{selectedPlayers}" dropEnabled="true" labelField="name"/>
              <mx:Form>
                  <mx:FormItem label="All players count">
                      <mx:Label text="{allPlayers.length}"/>
                  </mx:FormItem>
                  <mx:FormItem label="Selected players count">
                      <mx:Label text="{selectedPlayers.length}"/>
                  </mx:FormItem>
              </mx:Form>
          </mx:Application>

           

           

          Does this help?

           

          Dany

          1 person found this helpful
          • 2. Re: Binding principles question
            John Hall Level 4

            It's not exactly what I'm talking about but sure close enough so that I can add a button and a little script based on your example and then repose the question. Thanks for taking the time, Dany!!

             

            So I removed the dragMove because I want to keep the original data on the left side. If I click the button before dragging Pele over to the right side box, it updates fine. However, once I drag it to the other box, the script has no effect on the right side data. I'm trying to understand the principle of how, if I change the original source, databinding could help me update other places that reference that same data.

             

            <?xml version="1.0" encoding="utf-8"?>
            <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                            layout="horizontal"
                            creationComplete="init()">

             

                <mx:Script>
                    <![CDATA[
                        import mx.events.DragEvent;
                        import mx.collections.ArrayCollection;

             

                        [Bindable]
                        private var allPlayers:ArrayCollection = new ArrayCollection();
                        [Bindable]
                        private var selectedPlayers:ArrayCollection = new ArrayCollection();

             

                        private function init():void {
                            var apa:Array = [ { id: 1 , name: "Pele" } , { id: 1 , name: "Maradona" } , { id: 1 , name: "Platini" } , { id: 1 , name: "The Pope" } ];
                            allPlayers.source = apa;
                        }

             

                        protected function button1_clickHandler( event:MouseEvent ):void {
                            for ( var i:uint = 0 ; i < allPlayers.length ; i++ ) {
                                if ( allPlayers.getItemAt( i ).name == "Pele" ) {
                                    allPlayers.setItemAt( "Becker" , i );
                                    break;
                                }
                            }
                        }
                    ]]>
                </mx:Script>

             

                <mx:List dataProvider="{allPlayers}"
                         dragEnabled="true"
                         labelField="name"
                         dragMoveEnabled="true"/>
                <mx:List dataProvider="{selectedPlayers}"
                         dropEnabled="true"
                         labelField="name"/>
                <mx:Button label="Change Pele to Becker"
                           click="button1_clickHandler(event)"/>
                <mx:Form>
                    <mx:FormItem label="All players count">
                        <mx:Label text="{allPlayers.length}"/>
                    </mx:FormItem>
                    <mx:FormItem label="Selected players count">
                        <mx:Label text="{selectedPlayers.length}"/>
                    </mx:FormItem>
                </mx:Form>
            </mx:Application>

            • 3. Re: Binding principles question
              archemedia Level 4

              Check this:

               

               

              <?xml version="1.0" encoding="utf-8"?>
              <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                              layout="horizontal"
                              creationComplete="init()">

               

               

               

                  <mx:Script>
                      <![CDATA[
                          import mx.events.DragEvent;
                          import mx.collections.ArrayCollection;

               

               

               

                          [Bindable]
                          private var allPlayers:ArrayCollection = new ArrayCollection();
                          [Bindable]
                          private var selectedPlayers:ArrayCollection = new ArrayCollection();

               

               

               

                          private function init():void {
                              var apa:Array = [ { id: 1 , name: "Pele" } , { id: 1 , name: "Maradona" } , { id: 1 , name: "Platini" } , { id: 1 , name: "The Pope" } ];
                              allPlayers.source = apa;
                          }

               

               

               

                          private function button1_clickHandler( event:MouseEvent ):void {
                             
                              /* for ( var i:uint = 0 ; i < allPlayers.length ; i++ ) {
                                  if ( allPlayers.getItemAt( i ).name == "Pele" ) {
                                      allPlayers.setItemAt( "Becker" , i );
                                      break;
                                  }
                              } */
                              allPlayers.source.forEach(changeName);
                              selectedPlayers.source.forEach(changeName);
                             
                              allPlayers.refresh();
                              selectedPlayers.refresh();
                          }
                         
                          private function changeName(item:*, index:int, array:Array):void
                          {
                              if (item.name == "Pele")
                                  item.name = "Becker";
                          }
                      ]]>
                  </mx:Script>

               

               

               

                  <mx:List dataProvider="{allPlayers}"
                           dragEnabled="true"
                           labelField="name"/>
                  <mx:List dataProvider="{selectedPlayers}"
                           dropEnabled="true"
                           labelField="name"/>
                  <mx:Button label="Change Pele to Becker"
                             click="button1_clickHandler(event)"/>
                  <mx:Form>
                      <mx:FormItem label="All players count">
                          <mx:Label text="{allPlayers.length}"/>
                      </mx:FormItem>
                      <mx:FormItem label="Selected players count">
                          <mx:Label text="{selectedPlayers.length}"/>
                      </mx:FormItem>
                  </mx:Form>
              </mx:Application>

               

               

               

              Dany

              • 4. Re: Binding principles question
                archemedia Level 4

                The whole trick is to let your functions handle the ArrayCollection or the source array of the ArrayCollection.

                If you work on the source, check out the various function of the Array class, like filter, some and forEach, they're great!

                 

                If you work on the source, remember to call the refresh function on the ArrayCollection object itself, to trigger data binding.

                If you work on the ArrayCollection itself (like addItemAt or removeItemAt), data binding will occur automatically.

                 

                Dany

                • 5. Re: Binding principles question
                  John Hall Level 4

                  I totally appreciate your time and example. I'm currently iterating over the collections kind of like you mention but I assumed that I was maybe missing something about databinding since I assume arrayCollections update by reference, rather than copies, so I thought maybe there was a simple thing that I was missing such as not making the custom vos implement IDispatcher. On the other hand, if you would approach it this way, that's good enough for me. I'm going with it and you get those oh so coveted points ;-)

                   

                  Thanks again for taking the time.

                  • 6. Re: Binding principles question
                    archemedia Level 4

                    Thanks for the points but the main goal is to improve application concept design.

                    If you adapt the principle to let data binding work for you and just work with the dataproviders, then in fact you are adapting the mvc pattern (model, view, controller). In large applications, you could then centralize ArrayCollections in singleton classes and bind grids and lists to various Collections.

                     

                    Glad to have helped a little. Come again whenever your like

                     

                    Dany