<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.pabloprieto.net/index.php/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Pablo Prieto - Blog - délégation</title>
  <link>http://blog.pabloprieto.net/index.php/</link>
  <description>&quot;Faire des sites web c'est pas facile tous les jours&quot;</description>
  <language>fr</language>
  <pubDate>Fri, 19 Mar 2010 06:31:23 +0100</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Actionscript : délégation et passage d'arguments</title>
    <link>http://blog.pabloprieto.net/index.php/post/2007/03/05/Actionscript-%3A-delegation-et-passage-darguments</link>
    <guid isPermaLink="false">urn:md5:e84b3bc541bf39be664b3fc26801d4ff</guid>
    <pubDate>Mon, 05 Mar 2007 10:40:00 +0100</pubDate>
    <dc:creator>Pab.</dc:creator>
        <category>Actionscript/Flash/Flex</category>
        <category>actionscript</category><category>délégation</category><category>flash</category>    
    <description>&lt;p&gt;Le principe de la délégation en Actionscript&amp;nbsp;: à quoi ça sert, comment bien l'utiliser, contourner le problème du passage de paramètres et enfin ce qui va changer en AS 3.&lt;/p&gt;    &lt;h3&gt;La délégation&amp;nbsp;: à quoi ça sert&lt;/h3&gt;


&lt;p&gt;Un cas très courant nécessitant la délégation se présente dans l'exemple suivant&amp;nbsp;: un objet graphique (héritant de MovieClip) possède un bouton qui exécute une fonction de l'objet lorsque on lui clique dessus&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
Class MonObjet extends MovieClip{

	private var monBouton:MovieClip;

	public function MonObjet(){	
		monBouton.onRelease = this.faitUnTruc;
	}
	
	public function faitUnTruc(){
		trace(this);
	}

}
&lt;/pre&gt;


&lt;p&gt;Explication&amp;nbsp;: je passe la fonction faitUnTruc en référence à monBouton.onRelease. Ainsi, lorsque je vais cliquer sur monBouton, la fonction faitUnTruc sera exécutée. Enfin dans la fonction faitUnTruc, je fais un trace de l'objet courant (this).&lt;/p&gt;


&lt;p&gt;Et bien dans cette situation, this fera référence non pas à l'occurrence de MonObjet, mais à celle du bouton&amp;nbsp;! La faute au passage par référence de la fonction faitUnTruc à monBouton.onRelease&amp;nbsp;: la fonction faitUnTruc s'exécute bien, mais dans le &quot;scope&quot; du bouton, c'est à dire comme une fonction du bouton, et non de l'objet.&lt;/p&gt;


&lt;h3&gt;Mise en place de la délégation avec la classe Delegate&lt;/h3&gt;


&lt;p&gt;C'est à ce moment précis qu'arrive la classe Delegate pour contourner ce problème de manière simple et élégante. Cette classe, écrite par Mike Chambers, est disponible depuis Flash MX 2004. Voici la modification à apporter à notre exemple de départ&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
import mx.utils.Delegate;

Class MonObjet extends MovieClip{

	private var monBouton:MovieClip;

	public function MonObjet(){	
		monBouton.onRelease = Delegate.create(this, faitUnTruc);
	}
	
	public function faitUnTruc(){
		trace(this);
	}

}
&lt;/pre&gt;


&lt;p&gt;On commence par importer la classe qui se trouve dans le package mx.utils. Ensuite, au lieu de faire référence directement à la fonction faitUnTruc, on fait référence à la méthode statique Delegate.create avec deux arguments&amp;nbsp;: le premier est le scope, c'est à dire l'objet quoi doit garder la référence, et le deuxième est la fonction à exécuter. Cette fois bingo, this dans la fonction faitUnTruc désigne bien l'objet.&lt;/p&gt;


&lt;p&gt;Pour résumer, lorsque j'écris&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
Delegate.create(UnObjet, faitUnTruc);
&lt;/pre&gt;


&lt;p&gt;Cela peut se traduire par&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&quot;Exécute la fonction faitUnTruc comme étant une fonction de l'objet UnObjet&quot;&lt;/p&gt;


&lt;h3&gt;Passer des arguments&lt;/h3&gt;


&lt;p&gt;Passée l'euphorie (si si...), on tombe assez vite sur le prochain problème (ah flûte...)&amp;nbsp;: Delegate ne permet pas de passer de paramètres à la fonction appelée. Imaginons que la méthode faitUnTruc doit pouvoir recevoir un ou plusieurs paramètres pour s'exécuter correctement, on ne peut pas les spécifier au moment de la délégation.&lt;/p&gt;


&lt;p&gt;Il existe heureusement plusieurs techniques pour pouvoir le faire quand même&amp;nbsp;:&lt;/p&gt;


&lt;h4&gt;Rajouter des propriétés à la méthode appelante&lt;/h4&gt;


&lt;p&gt;Ne jamais oublier LE truc chouette en Actionscript&amp;nbsp;: (presque) tout est objet, donc une fonction est un objet. Et comme n'importe quel objet je peux donc lui rajouter des propriétés... c'est le principe de cette première solution&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
import mx.utils.Delegate;

Class MonObjet extends MovieClip{

	private var monBouton:MovieClip;

	public function MonObjet(){
		var d = Delegate.create(this, faitUnTruc);
		d.p1 = &amp;quot;toto&amp;quot;;
		d.p2 = 42;
		monBouton.onRelease = d;
	}
	
	public function faitUnTruc(){
		trace(arguments.caller.p1+&amp;quot;,&amp;quot;+arguments.caller.p2);
	}

}
&lt;/pre&gt;


&lt;p&gt;Je passe en référence à monBouton.onRelease une fonction qui est elle-même une référence à Delegate.create(this, faitUnTruc), à laquelle j'ai rajouté au préalable deux propriétés p1 et p2. Celle-ci est ensuite disponible dans la fonction faitUnTruc grâce à arguments.caller. C'est une solution simple et rapide, mais pas très propre car elle nécessite de connaître le nom des propriétés dans la fonction appelée.&lt;/p&gt;


&lt;h4&gt;Relegate&lt;/h4&gt;


&lt;p&gt;&lt;a href=&quot;http://www.tekool.net/&quot; hreflang=&quot;fr&quot;&gt;Tekool&lt;/a&gt; nous propose sur son site &lt;a href=&quot;http://www.tekool.net/flash/class/relegate/&quot; hreflang=&quot;fr&quot;&gt;une méthode&lt;/a&gt; plus élégante et moins verbeuse sous la forme d'une fonction Relegate qui ressemble en tous points à Delegate, excepté qu'elle accepte des paramètres supplémentaires qui seront transmis à la fonction appelée. Voici comment l'utiliser dans notre exemple&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
import Relegate;

Class MonObjet extends MovieClip{

	private var monBouton:MovieClip;

	public function MonObjet(){
		monBouton.onRelease = Relegate.create(this, faitUnTruc, &amp;quot;toto&amp;quot;, 42);
	}
	
	public function faitUnTruc(p1,p2){
		trace(p1+&amp;quot;,&amp;quot;+p2);
	}

}
&lt;/pre&gt;


&lt;h3&gt;La délégation et ActionScript 3&lt;/h3&gt;


&lt;p&gt;Attention car avec ActionScript 3 tout ceci va changer&amp;nbsp;! Oui en gros tout ce que j'ai écrit juste au dessus sera bientôt obsolète (et l'est déjà pour les gens qui développent sous Flex 2)&amp;nbsp;!&lt;/p&gt;


&lt;p&gt;Le tout nouveau modèle événementiel, basé sur celui du DOM Level 3, permet donc que le scope soit conservé lors du passe d'une fonction par référence&amp;nbsp;! Ainsi en reprenant l'exemple inital en AS3&amp;nbsp;:&lt;/p&gt;

&lt;pre&gt;
package{

	Class MonObjet extends MovieClip{

		private var monBouton:MovieClip;

		public function MonObjet(){
			monBouton.onRelease = this.faitUnTruc;
		}
	
		public function faitUnTruc(){
			trace(this);
		}

	}

}
&lt;/pre&gt;


&lt;p&gt;le this à l'intérieur de la fonction faitUnTruc désignera bien l'occurrence de MonObjet, et non plus le bouton, ce qui est quand même plus simple ;)&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.pabloprieto.net/index.php/post/2007/03/05/Actionscript-%3A-delegation-et-passage-darguments#comment-form</comments>
      <wfw:comment>http://blog.pabloprieto.net/index.php/post/2007/03/05/Actionscript-%3A-delegation-et-passage-darguments#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.pabloprieto.net/index.php/feed/rss2/comments/18</wfw:commentRss>
      </item>
    
</channel>
</rss>