Avatar billede seventhsun Nybegynder
18. juli 2008 - 15:19 Der er 9 kommentarer

Hvordan kan jeg lave f.eks en loadxml class?

Jeg er nybegynder ift. AS3 og prøver at benytte og lære nogle af de mere smarte muligheder.
Som f.eks eksterne .as filer med classes man kan bruge til andre projekter.

Og til at starte med, kunne jeg godt tænke mig at lave en class, der kan hente XML data.

Jeg forestiller mig noget ala:

package {
    import flash.display.Sprite;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.Event;

    public class loadxml extends Sprite {
        protected var loader:URLLoader;

        public function loadxml(url) {
            loader:URLLoader = new URLLoader();
            loader.addEventListener(Event.COMPLETE,onXMLLoad);
            loader.load(new URLRequest(url));
        }
        protected function onXMLLoad(event:Event):void {
            var xml:XML = new XML(loader.data);
            return;
        }
    }
}

Hvor jeg så i selve fla'en kunne skrive:

import loadxml;

loadxml("data.xml");

Men det virker ikke :-(

Herover har jeg skrevet return som resultatet af funktionen, men jeg er i tvivl om det er det rigtige at gøre.
Måske skulle jeg sende en variabel med, og så give værdien af xml til den?
Avatar billede maqhem Nybegynder
18. juli 2008 - 15:45 #1
Du bruger package, class og extends, når vi snakker om klasser, og når vi gør det, skal du ikke bruge import, men lave en ny instans af klassen:

var LoadXMLInstans:loadxml = new loadxml("data.xml"); // Du bør i øvrigt lave klassenavne med store begyndelsesbogstaver

Og hvis du ikke returnerer noget i din funktion, behøver du ikke at have en return. Du kan bare stoppe din kode. Man bruger kun return som du har gjort det, hvis man skal stoppe et sted midt i en funktion:

var Counter:int = 1;
Tæl();
function Tæl():void {
    trace("Tæl() blev kaldt. Hvis Counter er mindre end eller lig med fem, fortsætter vi. Er den det?");
    if(Counter > 2) {
        trace("Nix, det er den ikke.");
        return;
    }
    trace("Ja. Lige nu er Counter", Counter + ".");
    Counter++;
    Tæl();
}

Og lad være med at bruge protected. Gør brug af private i stedet - med mindre du selvfølgelig ved, din klasse skal nedarves igen, og den skal gøre brug af funktionen. Og du må ikke fasttype din egenskab to gange. Så slet ":URLLoader" i din constructor. Desuden skal du passe på med at have navne, som allerede findes i Flash' repetoire af predefinerede metoder og egenskaber. Så omdøb venligst din loader-instans og din event-parameter. Og så kan du til slut gøre det endnu mere dynamisk ved at udskifte den direkte tilgang (loader.data) med en tilgang, der går gennem parametren event - det er derfor, den er der: event.target.data.
Og så er det noget ævl at lave en klasse, der extender Sprite, hvis den overhovedet ikke skal addes til nogen DisplayObjectContainer.
Avatar billede maqhem Nybegynder
18. juli 2008 - 15:50 #2
Så den færdige kode ser sådan her ud:

---
package {
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.Event;

    public class LoadXml {
        private var LoaderObject:URLLoader;

        public function LoadXml(Url:String) {
            LoaderObject = new URLLoader();
            LoaderObject.addEventListener(Event.COMPLETE, OnXMLLoad);
            LoaderObject.load(new URLRequest(url));
        }
        private function OnXMLLoad(e:Event):void {
            var Xml:XML = new XML(e.target.data);
            trace(Xml);
        }
    }
}
---

Og i Flash:

---
var LoadXMLInstans:LoadXml = new LoadXml("data.xml");
---
Avatar billede maqhem Nybegynder
18. juli 2008 - 15:51 #3
Og man må gerne, i modsætning til AS2, fasttype constructoren. Men ikke til andet end void. Jeg gør det nu alligevel altid for helhedens skyld :)
Avatar billede seventhsun Nybegynder
22. juli 2008 - 15:20 #4
Det ser fornuftigt ud.
Tak for det :-)

Jeg kan desværre ikke lige teste det selv, så jeg kan ikke fortælle endnu om jeg kan få det til at virke.
Avatar billede seventhsun Nybegynder
23. juli 2008 - 14:47 #5
Ok, det virker som sådan.

Jeg har dog det problem, at jeg gerne vil sende min XML data videre til en skræddersyet function, alt efter hvilken data jeg får.
Så det ville være rart, hvis jeg kunne sende et funktionsnavn med som parameter til LoadXml.
Jeg ved bare ikke hvordan jeg så kalder denne funktion, når jeg ikke ved hvad navnet på den er?

Så noget i retning af:

var LoadXMLInstans:LoadXml = new LoadXml("data.xml", functionName);

Og i LoadXml.as:

    Når XMLen er loadet
    private function OnXMLLoad(e:Event, functionName):void {
            var Xml:XML = new XML(e.target.data);
            funtionName(Xml);
        }
Avatar billede maqhem Nybegynder
23. juli 2008 - 15:08 #6
Det er ikke nogen holdbar løsning. Lav din egen custom EventListener:

---

var LoadXMLInstans:LoadXml = new LoadXml("data.xml");
LoadXMLInstans.addEventListener(LoadXMLEvent.DATA_LOADED, DinFunktion);
function DinFunktion(e:LoadXMLEvent):void {
    // Skræddersyet funktion... Xml'en kan du gøre brug af med e.Xml:
    trace(e.Xml);
}

---

// LoadXML.as
package {
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.Event;
    import LoadXMLEvent;

    public class LoadXml {
        private var LoaderObject:URLLoader;

        public function LoadXml(Url:String):void {
            LoaderObject = new URLLoader();
            LoaderObject.addEventListener(Event.COMPLETE, OnXMLLoad);
            LoaderObject.load(new URLRequest(url));
        }
        private function OnXMLLoad(e:Event):void {
            var Xml:XML = new XML(e.target.data);
            dispatchEvent(new LoadXMLEvent(Xml, LoadXMLEvent.DATA_LOADED));
        }
    }
}

---

// LoadXMLEvent.as
package {
    import flash.events.Event;

    public class LoadXMLEvent extends Event {
        public const DATA_LOADED:String = "LoadXMLEvent_DataLoaded";
        private var XmlData:XML;

        public function LoadXMLEvent(Data:XML, Type:String, Bubbles:Boolean = false, Cancalable:Boolean = false):void {
            super(Type, Bubbles, Cancalable);
            XmlData = Data;
        }
        public function get Xml():XML {
            return XmlData;
        }
        public override function clone():LoadXMLEvent {
            return new LoadXMLEvent(XmlData, type, bubbles, cancalable);
        }
    }
}

---

Det er ikke lige testet efter, men jeg tror, det virker.
Avatar billede maqhem Nybegynder
23. juli 2008 - 15:09 #7
Det kan godt være, at metoden clone skal fasttypes Event i stedet for LoadXMLEvent. Det finder du ud af, hvis ovenstående giver en fejl ;)
Avatar billede seventhsun Nybegynder
23. juli 2008 - 16:55 #8
Øv.

Én ting er at jeg ikke kan gennemskue hvad LoadXMLEvent skal gøre godt for.
En anden ting er at det giver fejl som jeg ikke forstår:

1061: Call to a possibly undefined method addEventListener through a reference with static type LoadXml.
1119: Access of possibly undefined property DATA_LOADED through a reference with static type Class.
Avatar billede maqhem Nybegynder
23. juli 2008 - 18:48 #9
public const DATA_LOADED:String = "LoadXMLEvent_DataLoaded";

skal i hvert fald være:

public static const DATA_LOADED:String = "LoadXMLEvent_DataLoaded";

Måske det duer nu.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester