11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour tout le monde,

J'utilise les objets en PHP et j'utilise prototype.js.
Comme je n'ai pas encore pris le temps de regarder comment est fait le développement objet en javascript, je m'y mets.

Tout d'abord voici ma classe :

var Map = Class.create(
	{
		initialize : function(DefinitionMap)
		{
			this.MapJson = DefinitionMap.evalJSON();
		},
		AfficheDetailCase : function(CaseIndex)
		{
			var SpanText = document.createElement("span");
			var myText = document.createTextNode( "Coordonnées de la case : X= "+this.MapJson.Cases[CaseIndex].CoordX + "/ Y= " + this.MapJson.Cases[CaseIndex].CoordY );
			SpanText.appendChild(myText);
			$('DetailCase').appendChild(SpanText);
		},
		AfficheCasesVide : function(myParams, Conteneur)
		{
			IndexCase = 0;
			for(i=1;i<=myParams["NbCasesY"];i++)
			{
				for (j=1;j<=myParams["NbCasesX"];j++)
				{
					var CaseAffiche = document.createElement("div");
					CaseAffiche.id = "Case|"+j+"|"+i;
					CaseAffiche.className = "MapCaseVide";
					var myText = document.createTextNode( i + "/" + j );
					CaseAffiche.appendChild(myText);
					Conteneur.appendChild(CaseAffiche);
					
					CaseAffiche.onclick = function() { this.AfficheDetailCase(IndexCase); }
					
					if (j == myParams["NbCasesX"])
					{
						var DivBoth = document.createElement("div");
						DivBoth.style.clear = "both";
						Conteneur.appendChild(DivBoth);
					}
					IndexCase++;
				}
			}
			this.AjouteCasesurMap();
		},
		AjouteCasesurMap : function()
		{
			for (TmpCase in this.MapJson.Cases)
			{
				if(!Array.prototype[TmpCase])
				{
					$('Case|'+this.MapJson.Cases[TmpCase].CoordX+'|'+this.MapJson.Cases[TmpCase].CoordY).className = this.MapJson.Cases[TmpCase].Terrain;
				}
			}
		}
	}
)


j'ai un fichier JSON qui me permet de donner les propriétés de chaques cases de la carte (positions, image de fond, etc ..)

Là où je bloque c'est dans cette ligne :

CaseAffiche.onclick = function() { this.AfficheDetailCase(IndexCase); }


this fait référence à CaseAffiche et non plus à ma classe.

Comment dois-je faire pour utiliser une méthode de ma classe à cet endroit?

merci de vos éclaircissement Smiley cligne
Modifié par Leorilan (10 Sep 2009 - 13:32)
merci pour ta réponse publicaccount.

J'ai lu et relu ce que tu propose.
J'ai lu d'autres choses sur le web :
http://www.coursweb.ch/javascript/apply-call.html
http://alternateidea.com/blog/articles/2007/7/18/javascript-scope-and-binding

Mais soit je suis une buse (ce qui n'est pas exclu Smiley biggrin ), soit j'en ai trop dans la tête et je ne vois plus clair ...

Dans mon cas, je ne vois pas bien où mettre le bind().
J'ai tenté :
CaseAffiche.onclick = function() { this.AfficheDetailCase(IndexCase); }.bind(this);


Mais sur le click, il me dit : this.MapJson.Cases[CaseIndex] is undefined

Ce que je comprend, c'est que lorsqu'il veut faire AfficheDetailCase() il a de nouveau perdu sa référence à la propriété this.MapJson.

Si quelqu'un peut m'éclairer un peu, ou si quelqu'un a un lien un peu plus clair.

Merci d'avance
Tu as bien mis le bind au bon endroit. Preuve en est, this ne fait plus référence à "CaseAffiche", mais à ton instance de la classe Map (tu arrive à invoquer ta méthode, cqfd).

Je pencherai plutôt vers "IndexCase" qui n'a pas la valeur que tu attends au moment de l'execution.

Quand tu associe ton callback à l'évènement onclick la variable "IndexCase" n'est pas évaluée tout de suite, il y a juste une référence vers le callback qui est placée en mémoire.
Ensuite tu boucle, tu incrémente "IndexCase", etc.

Enfin vient le moment ou tu clique, ton évènement se déclenche, le callback est évalué, et la C'EST LE DRAME : IndexCase est maintenant égal à "toto".
Bref le coup classique du compile-time VS run-time (abus de langage car le javascript n'est pas compilé, mais bon le principe est le même).

La solution, ne pas "binder" seulement ton contexte d'execution, mais aussi une copie de la valeur contenue dans "IndexCase".
Pour cela tu as plein de solution, faire une fonction enveloppante qui retourne ton cb (callback) avec en argument ta valeur, mettre ta valeur en propriété de ton cb (les fonctions sont des objets dynamiques en js), etc.
Modifié par publicaccount (10 Sep 2009 - 16:41)
merci pour ces précieux renseignements publicaccount.

Après relecture de ce que j'avais fait, je me suis heurté à cette évidence.

Je vais de ce pas me renseigner sur les solutions que tu propose.