Frage

(EDIT: Ich habe bearbeitet meine Frage es einfacher zu machen,         sorry, wenn einige Antworten sind aus dem Zusammenhang gerissen)

Ich habe einen reduzierten Testfall für meine Frage vorbereitet:

alt text

Ich versuche, eine benutzerdefinierte Komponente zu schaffen, das ist werden mit XML-Daten kommen vom Server zugeführt. Mein Problem ist, dass der Zuhörer Collection nicht gefeuert werden und damit Etiketten nicht aktualisiert -

Games.mxml (meine benutzerdefinierte Komponente mit Hörer):

<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 (klicken Sie auf die Tasten, um Änderung XML):

             

        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}"/>

Bitte geben Sie mir, was los ist.

Viele Grüße, Alex

UPDATE: Games.mxml bearbeitet, wie durch clownbaby vorgeschlagen - noch nicht funktioniert (xlistChanged wird nie aufgerufen):

<?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>
War es hilfreich?

Lösung

Zwei Dinge:

1) Der Grund Ihrer Veranstaltung feuert nicht, weil Sie den Hörer nach dem Satz _xlist hinzufügen.

2) Sie sollten nicht ein Ereignis-Listener in Ihrem Setter sowieso hinzufügen. Sie sollten es auf dem Initiieren oder creationComplete- Ereignisse Ihrer VBox Komponente hinzuzufügen.

Bearbeiten

In Ordnung, nachdem in Ihrem Code suchte wieder kann ich sehe das Problem ... so nur noch ein paar Dinge.

3) Warum sind Sie eine Methode init zu nennen, wenn es auf creationComplete aufgerufen wird? Sie sollten in geeigneter Weise von Benennungsmethoden in die Gewohnheit. Zum Beispiel ist die Methode, die auf creationComplete aufgerufen wird, sollte genannt werden: onCreationComplete oder handleCreationComplete Auf diese Weise werden Sie wissen, was Ihre Code 6 Monate auf der Straße tut

.

4) Dies ist Ihr Hauptproblem: Sie verwenden die Getter / Setter in geeigneter Weise. Wenn Sie einen Setter haben, sollten Sie auch einen Getter implementieren (wenn Sie ein Nur-Schreib-Feld haben). Noch wichtiger ist, sollten Sie Verwendung der Getter auf Ihre Daten zuzugreifen. In Ihrem xListChanged Methode verwenden Sie die Setter Sie definiert haben, so wird nichts gesagt, immer die _xlist tatsächlich geändert. Als solche sollten Sie Ihren Code ändern:

private var _xlist:XMLListCollection;

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

Wenn Sie den Zugriff auf _xlist möchten, verwenden Sie das Getter. Ändern Sie beispielsweise die Datenprovider Ihrer List Komponente {xlist} zu sein. Und die xListChanged Methode sein sollte, den Getter verwenden. xlist statt den direkten Zugriff auf das Element _xlist

Andere Tipps

Warum gehst du nicht einfach dies tun:

  

public function set 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() + ')';
     

}

Sie brauchen keinen Zuhörer, wenn der einzige Weg, um das lokale _xlist Variable zu setzen, indem die xlist Eigenschaft festlegen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top