Question

(EDIT: Je l'ai modifié ma question pour le rendre plus simple,         désolé si certaines réponses sont hors contexte)

J'ai préparé un test réduit pour ma question:

text alt

Je suis en train de créer un composant personnalisé qui est étant alimenté avec des données XML provenant du serveur. Mon problème est que l'auditeur CollectionEvent ne soit pas tiré et étiquettes donc pas mis à jour -

Games.mxml (mon composant personnalisé avec l'auditeur):

<mx:Script>
    <![CDATA[
        import mx.events.*;

        private var _xlist:XMLList;

        [Bindable]
        public function get xlist():XMLList {
            return _xlist;
        }

        public function set xlist(x:XMLList):void {
            _xlist = x;
            trace("set(" + x +")");
            list.dataProvider = x;
            list.dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE, xlistChanged);                
        }

        private function gameLabel(item:Object):String {
            return "game: " + item.@label;
        }

        private function xlistChanged(event:CollectionEvent):void {
            trace("xlistChanged(" + event +")");
            all.text = "All games: " + _xlist.game.length();
            full.text = "Full games: " + _xlist.game.(user.length() == 3).length();
            vacant.text = "Vacant games: " + _xlist.game.(user.length() < 3).length();
        }
    ]]>
</mx:Script>

<mx:Label id="all" text="All games"/>
<mx:Label id="full" text="Full games"/>
<mx:Label id="vacant" text="Vacant games"/>

<mx:List id="list" labelFunction="gameLabel"/>

MyTest.mxml (cliquez sur les boutons à XML du changement):

             

        private function changeXML1():void {
            games = <games>
                        <game label="1">
                            <user/>
                            <user/>
                            <user/>
                        </game>
                        <game label="2">
                            <user/>
                            <user/>
                        </game>
                        <game label="3">
                            <user/>
                            <user/>
                            <user/>
                        </game>
                    </games>;                   
        }

        private function changeXML2():void {
            games = <games>
                        <game label="A">
                            <user/>
                            <user/>
                            <user/>
                        </game>
                        <game label="B">
                            <user/>
                            <user/>
                        </game>
                        <game label="C">
                        </game>
                    </games>;                   
        }
    ]]>
</mx:Script>

<mx:XML id="games">
    <games>
        <game label="X">
            <user/>
            <user/>
        </game>
        <game label="Y">
            <user/>
            <user/>
        </game>
    </games>
</mx:XML>

<mx:Button label="Change XML 1" click="changeXML1()"/>
<mx:Button label="Change XML 2" click="changeXML2()"/>
<my:Games xlist="{games.game}"/>

S'il vous plaît me conseiller ce qui est faux.

Cordialement, Alex

Mise à jour: édité Games.mxml comme suggéré par clownbaby - ne fonctionne toujours pas (xlistChanged est jamais invoqué):

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" 
         xmlns:my="*" creationComplete="onCreationComplete(event)">

    <mx:Script>
        <![CDATA[
            import mx.events.*;

            private var _xlist:XMLList;

            [Bindable]
            public function get xlist():XMLList {
                return _xlist;
            }

            public function set xlist(x:XMLList):void {
                _xlist = x;
                list.dataProvider = x;
                trace("\n set: " + x);
            }

            private function gameLabel(item:Object):String {
                return "game: " + item.@label;
            }

            private function onCreationComplete(event:FlexEvent):void {
                list.dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE, xlistChanged);
            }

            private function xlistChanged(event:CollectionEvent):void {
                all.text = "All games: " + xlist.length();
                full.text = "Full games: " + xlist.(user.length() == 3).length();
                vacant.text = "Vacant games: " + xlist.(user.length() < 3).length();
            }
        ]]>
    </mx:Script>

    <mx:Label id="all" text="All games"/>
    <mx:Label id="full" text="Full games"/>
    <mx:Label id="vacant" text="Vacant games"/>

    <mx:List id="list" labelFunction="gameLabel"/>

</mx:VBox>
Était-ce utile?

La solution

Deux choses:

1) La raison pour laquelle votre événement ne se déclenche pas parce que vous ajoutez l'auditeur après avoir défini _xlist.

2) Vous ne devriez pas ajouterez un écouteur d'événements au sein de votre setter de toute façon. Vous devez l'ajouter sur initialize ou d'événements creationComplete de votre composant VBox.

EDIT

Bon, après avoir regardé à nouveau votre code, je peux voir le problème ... donc juste quelques petites choses.

3) Pourquoi vous nommez un init de méthode, quand il est appelé creationComplete? Vous devriez prendre l'habitude de nommer les méthodes de façon appropriée. Par exemple, la méthode qui est appelée sur creationComplete devrait être nommé: onCreationComplete ou handleCreationComplete De cette façon, vous saurez ce que votre code fait 6 mois sur la route

.

4) Ceci est votre principal problème: Vous utilisez les getters / setters en conséquence. Si vous avez un setter, vous devez également mettre en œuvre un getter (sauf si vous avez un champ d'écriture seule). Plus important encore, vous devez utiliser le getter pour accéder à vos données. Dans la méthode xListChanged vous n'utilisez pas le poseur que vous avez défini, donc rien obtient le dit _xlist réellement changé. En tant que tel, vous devez changer votre code:

private var _xlist:XMLListCollection;

[Bindable]
public function get xlist():XMLListCollection { return this._xlist; }
public function set xlist(value:XMLListCollection):void
{
    this._xlist = value;
}

Chaque fois que vous voulez _xlist d'accès, utilisez le getter. Par exemple, changer le fournisseur de données de votre composant List être {xlist}. Et la méthode xListChanged devrait utiliser le getter. xlist au lieu d'accéder directement au _xlist membre

Autres conseils

Pourquoi ne pas faire ceci:

  

fonction publique ensemble XList (x: XMLList): void {

   _xlist = new XMLListCollection(x);
   _all.label = 'All (' + _xlist.length + ')';

   var full:XMLList = _xlist.source.game.(user.length() == 3);
   _full.label = 'Full (' + full.length() + ')';

   var free:XMLList = _xlist.source.game.(user.length() < 3);
   _free.label = 'Free (' + free.length() + ')';
     

}

Vous n'avez pas besoin d'écoute si la seule façon de régler la variable _xlist locale est en définissant la propriété de xlist.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top