PDA

Volledige versie bekijken : Argument doorgeven aan listener functie


PageMaker
%Europe/Berlin %547 %2009, 14:08
Ik krijg de volgende deels onverklaarbare output:
aantal kinderen = 20
foto_url = images/IMG_0654.jpg fotoLoader.name = 0
foto_url = images/IMG_0655.jpg fotoLoader.name = 1
foto_url = images/IMG_0656.jpg fotoLoader.name = 2
foto_url = images/IMG_0674.jpg fotoLoader.name = 3
foto_url = images/IMG_0692.jpg fotoLoader.name = 4
foto_url = images/IMG_0720.jpg fotoLoader.name = 5
foto_url = images/IMG_0759.jpg fotoLoader.name = 6
foto_url = images/IMG_0784.jpg fotoLoader.name = 7
foto_url = images/IMG_0795.jpg fotoLoader.name = 8
foto_url = images/IMG_0815.jpg fotoLoader.name = 9
IMG WIDTH: 800 IMG HEIGHT: 533 fotoPointer: 10
IMG WIDTH: 533 IMG HEIGHT: 800 fotoPointer: 10
IMG WIDTH: 800 IMG HEIGHT: 533 fotoPointer: 10
IMG WIDTH: 800 IMG HEIGHT: 533 fotoPointer: 10
IMG WIDTH: 533 IMG HEIGHT: 800 fotoPointer: 10
IMG WIDTH: 800 IMG HEIGHT: 533 fotoPointer: 10
IMG WIDTH: 533 IMG HEIGHT: 800 fotoPointer: 10
IMG WIDTH: 800 IMG HEIGHT: 533 fotoPointer: 10
IMG WIDTH: 533 IMG HEIGHT: 800 fotoPointer: 10
IMG WIDTH: 800 IMG HEIGHT: 533 fotoPointer: 10

De code die deze output genereert is:
private function loadThumbnailSlider(): void
{
while ( fotoPointer < fotoCount )
{
var foto_url = fotoPath + fotoArray[ fotoPointer ] + '.jpg';
var fotoLoader:Loader = new Loader();
fotoLoader.load( new URLRequest( foto_url ));
fotoLoader.name = String( fotoPointer );

fotoLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, fotoLoaded );

trace( "foto_url = " + foto_url + " fotoLoader.name = " + fotoLoader.name ); // OK, dit werkt

fotoPointer++;

} // while

} // function loadThumbnailSlider

private function fotoLoaded( $evt: Event ): void
{

trace("IMG WIDTH: " + $evt.target.width + " IMG HEIGHT: " + $evt.target.height + " fotoPointer: " + fotoPointer );

} /// function fotoLoaded
fotoPointer is gedeclareerd als globale: var fotoPointer:Number = 0;

Ik verwachtte dat fotoPointer in de functie fotoLoaded beschikbaar zou zijn met de waarde die hij heeft op het moment van aanroepen van de listener; maar de heer Flash denkt daar (klaar blijkelijk) heel anders over.

Hoe kan ik nu toch de waarde van fotoPointer binnen de listener functie fotoLoaded ter beschiking krijgen?

Jan
%Europe/Berlin %566 %2009, 14:35
Die fotoPointer staat na een paar milliseconden al op 10, dus nog voordat je eerste foto geladen is.
Je zal die pointer op één of andere manier moeten koppelen aan je Loader instance, want niet alle foto's zijn even groot en de volgorde van 'gedaan met laden' zal niet (altijd) overeenkomen met de volgorde van laden.
Je zou een dictionary kunnen gebruiken om pointers aan loaders te koppelen:
import flash.utils.Dictionary;//<-----
private var _dict:Dictionary = new Dictionary();//<-----
private function loadThumbnailSlider(): void
{
while ( fotoPointer < fotoCount )
{
var foto_url = fotoPath + fotoArray[ fotoPointer ] + '.jpg';
var fotoLoader:Loader = new Loader();
fotoLoader.load( new URLRequest( foto_url ));
fotoLoader.name = String( fotoPointer );

fotoLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, fotoLoaded );

trace( "foto_url = " + foto_url + " fotoLoader.name = " + fotoLoader.name ); // OK, dit werkt

_dict[fotoLoader]=fotoPointer++;//<-------

}

}

private function fotoLoaded( $evt: Event ): void
{
trace(_dict[$evt.target.loader]);//<-----
trace("IMG WIDTH: " + $evt.target.width + " IMG HEIGHT: " + $evt.target.height + " fotoPointer: " + fotoPointer );

}

Meer uitleg en andere opties vind je hier:
http://www.flashfocus.nl/forum/showpost.php?p=340297&postcount=8

Groeten;
Jan

e.l.dam
%Europe/Berlin %567 %2009, 14:36
Je hebt hem binnen fotoLoaded ook wel beschikbaar, maar Flash draait eerst die eerste functie (while ...), en de fotoLoaded gooit hij pas al er een foto klaar is met laden.

10 fotos door een loopje halen gaat ERG snel, de eerste foto laden duurt misschien ook niet zo lang, maar dan is de functie in loadThumb.. al helemaal klaar.

Als je fotoLoader.name opvraagt, krijg je gewoon te zien welke foto het is. Dus e.currentTarget.name = 1 tm 10.

edit: Lame @ zelfde tijd reply posten. Anyway, je name opvragen geeft dus idd niet persé een lijstje van 1 2 3 4 .. etc, maar kan ook "door de war" staan.

Als je wilt "kijken of alles geladen is", kun je wel bij elke fotoLoaded een andere var bijmaken (zoals fotoPointer), en die vergelijken met fotoPointer. Zijn ze gelijk, dan is de laatste foto geladen.

PageMaker
%Europe/Berlin %577 %2009, 14:51
Je zou een dictionary kunnen gebruiken om pointers aan loader te koppelen.

Hoe zou dat dan moeten, want dit

Als je fotoLoader.name opvraagt,

lukt niet in de functie "fotoLoaded"; fout boodschap:

ReferenceError: Error #1069: Property name not found on flash.display.LoaderInfo and there is no default value.
at My_AS3_Foto_Gallery/::fotoLoaded()

Ik heb al eens zitten goochelen op "argumenten doorgeven aan een listenerfunctie" en dan vind ik dat ik een extentie van de Event klasse moet maken; maar is dat nu de enige mogelijkheid?

Jan
%Europe/Berlin %581 %2009, 14:57
Hoe zou dat dan moeten, want dit
Had net mijn post aangepast met een concreet voorbeeld. ;)

Groeten;
Jan

jaspermuts
%Europe/Berlin %582 %2009, 14:59
Die error krijg je denk ik omdat je $evt.target.name opvraagt in plaats van $evt.target.loader.name.
Je geeft de name aan de loader, maar de event wordt gedispatched door loader.contentLoaderInfo (= een instantie van LoaderInfo). Via $evt.target krijg je dus een LoaderInfo waarvan je via de loader eigenschap weer de loader kunt opvragen.

PageMaker
%Europe/Berlin %595 %2009, 15:17
Beiden dank! Ik ga er mee verder.
Op het net vond ik nog iemand met een gelijksoortig probleem; maar ik begrijp het antwoord niet - kan (wil) iemand dat toelichten?


I'm loading some images into an image gallery. I'm having trouble figuring out how to put each image into a Sprite so I can access the mouse events. When a users clicks on a image I would like to load an external page. Here is the code that I have:

function spaceImages():void{
mcContainer.x = 10;
mcContainer.y = 79;
for(var i:int = 0; i < images.length;i++){
images[i].x = images[i].width * i + padding;
mcContainer.addChild(images[i]);
}
}


We'd need to see how you're loading your images to help you. Are you using Loader? If so, Loader has all the same DisplayObject properties as Sprite so it's effectively already a Sprite. You can assign it to a varaible to make it easier to handle like this:


var obj:DisplayObject;
function loadComplete(event:Event):void
{
loader.contentLoaderInfo.removeEventListener(Event .INIT, loadComplete);
obj = loader.contentLoaderInfo.content;
}


Thanks for your help with this, it worked perfect.


Ik hou hier in elk geval aan over dat Loader dezelfde mogelijkheden biedt als Sprite; dat is weer winst!

@JasperMuts: dat werkt prima!!

jaspermuts
%Europe/Berlin %606 %2009, 15:33
Allereerst: het is geen soortgelijk probleem. Het gaat alleen allebei over foto's inladen.
Met het antwoord wordt bedoeld dat er veel dingen zijn die je met een Sprite kan die met een Loader ook kan. Zoals bijv addChild(de Loader) of deLoader.addEventListener() etc. Maar wat je precies met een bepaalde class kan moet je niet op het forum vragen, dat staat uitgebreid beschreven in je Flash Help of in de Adobe LiveDocs.

PageMaker
%Europe/Berlin %613 %2009, 15:43
OK,
Beide aangereikte oplossingen werken! De lijst staat - zoals te verwachten - inderdaad wel erg "door elkaar", niettemin kan ik er mee verder.
Nogmaals dank.