Anonymous EventListener eltávolítása

Posted: 8th March 2010 by szabolcs.fertaly in ActionScript
Tags: , ,

Az eseményekről nem írnék az alapjaitól, található egy rövidebb leírás erről az actionscript.hu-n.
Korábban már találkoztam azzal a fogalommal, hogy function closure, de még most sem tudom mi rá az igazán jó magyar fordítás, ezért a továbbiakban is így fogom használni, arról nem is beszélve, ha valaki a neten próbál a témában segítséget találni a témával kapcsolatban, akkor több sikerrel jár az angol elnevezésekkel.

Egy objektum eseményeire annak addEventListener metódusával tudunk feliratkozni, ahol a második paraméterben a típus megadása után egy függvényt kell megadni ami az esemény kezelését végzi.
Alap esetben a következőképp néz ki a kód:

 
	object.addEventListener(Event.COMPLETE,handler);
	function handler(event:Event):void
	{
		//esemény kezelése
	}

Természetesen nem árt gondoskodni a figyelők eltávolításáról. Ezt a removeEventListener metódus hívásával tudjuk megtenni.
Ez volt a bevezetés akkor jöhet a lényeg amire a címben is utaltam.
Amint elkezdünk dolgozni szerveroldali adatokkal, vagy file-okkal elkerülhetetlen, hogy megismerkedjünk az actionscript aszinkron tulajdonságával. Ez annyit tesz, hogy egy hívásra a válasz nem azonnal történik meg, a kód a hívás után fut tovább, nem vár az eredményre. A választ eseményfigyelőkkel tudjuk kezelni.
Vegyük pl. a HTTPService-t. Három eseményfigyelőt regisztráhatunk hozzá (result,fault,invoke).

Vegyük például a result eseményt:

	var service:HTTPService = new HTTPService();
	...
	...
	service.addEventListener(ResultEvent.RESULT,resultHandler);
 
	function resultHandler(result:ResultEvent):void
	{
		//válasz feldolgozása
	}

De vajon mi történik akkor, ha egy következő hívást kell ennek a hívásnak az eredményével meghívni. Ekkor a resultHandler-ben létrehozzuk a következő service-t , regisztrálunk hozzá eseményfigyelőt és meghívjuk a send() metódusát.

	var service:HTTPService = new HTTPService();
	...
	...
	service.addEventListener(ResultEvent.RESULT,resultHandler);
	service.send();
 
	function resultHandler(result:ResultEvent):void
	{
		var service2:HTTPService = new HTTPService();
		...
		...
		service.addEventListener(ResultEvent.RESULT),resultHandler2);
		service.send();
	}
 
	function resultHandler2(result:ResultEvent):void
	{
		//2. service eredményének kezelése
	}

És akkor most vegyük hozzá, hogy esetleg a hibákat is kéne kezelni. Könnyen átláthatatlanná válik a kód.
Ilyenkor jöhet jól a function closure.
Az előbbi kód a következőképp néz ki closure alkalmazásával:

	var service:HTTPService = new HTTPService();
	...
	...
	service.addEventListener(ResultEvent.RESULT,
		function(result:ResultEvent):void
		{
			var service2:HTTPService = new HTTPService();
			...
			...
			service.addEventListener(ResultEvent.RESULT),
			function(result:ResultEvent):void
			{
				//Eredmény kezelése
			});
			service.send();	
		});
	service.send();

És amiért a post igazából íródott, hogy ezt a closure-n keresztüli figyelőt, hogy lehet eltávolítani. Mivel ez anonym függvény nem lehet a szokásos módon eltávolítani a removeEventListener() metódussal mivel nincs neve. A következő megoldással azonban megoldható, hogy a figyelő eltávolításra kerüljön.

 
	class.addEventListener(Event.COMPLETE,
	function(evt:Event):void
	{
		(evt.target as EventDispatcher).removeEventListener(evt.type, arguments.callee);
	});

Minden függvénynek lekérdezhetőek az argumentumai az arguments lokális változón keresztül.
Ennek callee tulajdonsága tartalmazza a referenciát a függvényre ami meghívta, jelen esetben önmagát. És voilá eltávolítottuk a figyelőt.
Az Adobe azt javasolja, hogy az arguments objektum helyett a ... rest objektumot használjuk a függvény paramétereinek elérésére.

Bővebben a témáról:
arguments
… rest
function closure – 1
function closure 2

Gondolkodtam rajta, hogy írjam le ezt a problémát amivel szembesültem, aztán úgy döntöttem nem csak azt a 3 sort vágom be ami a megoldást adta, így hátha egy kicsivel több információt tudtam átadni és felkelteni az érdeklődést az eseményekkel kapcsolatban. Fogok még írni majd egy postot a témáról, mert az actionscript.hu-s post némi kiegészítésre szorulhat azok számára akik kicsit mélyebben is meg szeretnék érteni az eseményeket. Addig is jó olvasgatást.

You must be logged in to post a comment.