IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[POO] accès à une méthode


Sujet :

JavaScript

  1. #1
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut [POO] accès à une méthode
    Salut,
    Soit le petit script suivant qui crée une balise DIV et un gestionnaire d'événement avec onclick. Le souci c'est que dans cette méthode, le this renvoie au DIV et non plus l'objet. Ce qui fait que je ne peux plus accéder aux autres méthodes. Voyer la ligne en rouge dans le code ci-dessous.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function cityObj(name,id)
    {
    	
    	this.name = name
    	this.id = id
    	this.div = document.createElement("div");
    	this.div.id = this.id;
    	
    	this.createDiv = function(){
    		document.getElementById('container').appendChild(this.div);
    		this.div.appendChild(document.createTextNode(name));
    	}
    	
    	this.div.onclick = function(){
    		this.setForm() // ne fonctionne pas
    		document.getElementById('newForm').elements[0].focus()
    	}
    	
    	this.setForm = function(){
    		var content = '<form action="" method="POST" id="newForm">';
    		content += '<input type="text" name="data_'+this.id+'" value="'+this.name+'" />';
    		content += '</form>';		
    		this.div.innerHTML = content;
    	}
    }
    Comment appeler la méthode setForm depuis this.div.onclick ?

  2. #2
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Salut,

    regarde du coté des methodes call et apply elles permettent de
    définir le contexte this lors de l'appel d'une fonction. Mais ce
    n'est pas très pratique pour les appels événementiels.

    Regarde les fonctions bind et bindAsEventListener du
    framework prototype.js c'est propre.

  3. #3
    Membre averti Avatar de magnus2005
    Profil pro
    Ingenieur SI
    Inscrit en
    Avril 2005
    Messages
    454
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingenieur SI

    Informations forums :
    Inscription : Avril 2005
    Messages : 454
    Points : 331
    Points
    331
    Par défaut
    1
    J ai un doute sur ton onclick ?
    ça fonctionne bien sur tous les navigateurs ?

    2
    Pour le this
    Ton code est faux, il ne pas fonctionner car il est hors contexte.
    Quand tu ecris le code declarer dans function(){/*ton code*/}
    tu n es plus dans le contexte de ton objet [du point de vue de la POO] si tu rajoute à ça le modele POO miteux de javascript tu as peu de chance que this pointe sur l objet souhaité.
    Essaie de faire une fonction avec un eval

  4. #4
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    Change de nom de membre ^^

  5. #5
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    salut,
    Merci pour ta réponse. J'ai procédé un peu différement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    function cityObj(name,id)
    {
    	this.name = name
    	this.id = id
    	this.div = document.createElement("div");
    	this.div.id = 'div_'+this.id;
    	obj[id] = this;
     
    	this.createDiv = function(){
    		document.getElementById('container').appendChild(this.div);
    		this.div.appendChild(document.createTextNode(name));
    	}
     
    	this.div.onclick = setForm;
     
    }
     
    function setForm(event){
    	var curObj = getObj(this.id);
    	var content = '<form id="newForm">';
    	content += '<input type="text" name="data_'+curObj.id+'" value="'+curObj.name+'" />';
    	content += '</form>';
    	curObj.div.innerHTML = content;
    	document.getElementById('newForm').elements[0].focus()
    }
     
    function getObj(id){
    	var key=id.split('_')[1];
    	return obj[key];
    }

  6. #6
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Citation Envoyé par magnus2005
    ...le modele POO miteux de javascript...
    c'est un langage à prototype, il faut savoir s'y adapter, c'est tout.

    Julien était tout près de la solution. Voici ce qu'il manque. j'ai ajouté
    le html autour pour pouvoir tester facilement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Page Title</title>
    <script type="text/javascript">
     
    Function.prototype.bind = function(object) {
    	var __method = this;
    	return function() {
    		return __method.apply(object, arguments);
    	}
    }
     
    function cityObj(name,id)
    {	
    	this.name = name
    	this.id = id
    	this.div = document.createElement("div");
    	this.div.id = this.id;
     
    	this.createDiv = function(){
    		document.getElementById('container').appendChild(this.div);
    		this.div.appendChild(document.createTextNode(name));
    	}
     
    	this.div.onclick = function(){
    		this.setForm() // ne fonctionne pas
    		document.getElementById('newForm').elements[0].focus()
    	}.bind(this);
     
    	this.setForm = function(){
    		var content = '<form action="" method="POST" id="newForm">';
    		content += '<input type="text" name="data_'+this.id+'" value="'+this.name+'" />';
    		content += '</form>';		
    		this.div.innerHTML = content;
    	}
    }
     
    function init() {
    	new cityObj('nom', 'id_a').createDiv();
    }
    </script>
     
    </head><body onload='init();'>
     
    <div id='container'></div>
     
    </body></html>
    Le principe pour "rétablir" le context d'instance souhaité c'est
    d'appeler la fonction en lui donnant le context désiré.

    c'est faisable avec apply et call.

    Mais comme le "onclick" attend une référence à une fonction
    on peut lui donner une fonction anonyme qui contient cette
    référence et qui appelle la fonction de l'objet avec apply pour
    fixer le contexte.

    Ce problème étant fréquent dans une même page, c'est bien de
    disposer d'une fonction utilitaire pour faire cette liaison.

    Ce qui est encore plus pratique c'est d'étendre le prototype de
    l'object Function (j'ai bien dit objet Function)

    et ça donne ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Function.prototype.bind = function(object) {
    	var __method = this; 
            // crée une variable pour mémoriser le context (this) de la fonction bind(...), 
    	return function() {
                   // la variable __method est visible d'ici (ça s'appelle une "closure" sauf erreur)
                   // on appelle la methode apply en lui transmettant le context pour this (object) et les arguments de la fonction anonyme
    		return __method.apply(object, arguments);
    	}
    }

  7. #7
    Membre averti Avatar de magnus2005
    Profil pro
    Ingenieur SI
    Inscrit en
    Avril 2005
    Messages
    454
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingenieur SI

    Informations forums :
    Inscription : Avril 2005
    Messages : 454
    Points : 331
    Points
    331
    Par défaut
    Mea Culpa
    Je dirais plutot le modele Object de javascript est tres partiel ce qui peut induire en erreur toute personne se basant sur de la POO classic.
    D un point de vue objet c est pas coherent que le this contenu dans une fonction pointe sur un object.
    C est parce que la definition du this de javascript est variable ce qui est inconcevable du point de vie POO.

  8. #8
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    C est parce que la definition du this de javascript est variable
    En plus ca dépend du navigateur. C'est vrai que le this qui pointe sur l'élément déclencheur dans une callback d'événement c'est pratique mais bizzare.
    Quelqu'un pourrait m'expliquer cette histoire de prototype ? a quoi ca sert ?
    Personnellement je fais encore comme ca mais faudrait peut-être que j'évolue lol :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    function Obj {
     this.func = function f {
      // etc
    }
    }
    [edit]J'avais pas lu ton post marcha, j'ai l'impression que ca répond à ma question mais je comprends pas tout ^^. Surtout je vois pas où est le problème d'utiliser Obj.func() dans un onClick, par exemple [/edit]

  9. #9
    Membre confirmé Avatar de goodpz
    Profil pro
    Inscrit en
    Février 2007
    Messages
    475
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 475
    Points : 514
    Points
    514
    Par défaut
    Je dirais plutot le modele Object de javascript est tres partiel ce qui peut induire en erreur toute personne se basant sur de la POO classic.
    D un point de vue objet c est pas coherent que le this contenu dans une fonction pointe sur un object.
    C est parce que la definition du this de javascript est variable ce qui est inconcevable du point de vie POO.
    Comment ça partiel ? Le modèle POO de javascript est plus puissant que le modèle "classique" basé sur l'héritage. Par contre, il est clair que javascript est The World's Most Misunderstood Programming Language

  10. #10
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Citation Envoyé par Djakisback
    Quelqu'un pourrait m'expliquer cette histoire de prototype ? a quoi ca sert ?
    Le prototype c'est la listes des variables et fonctions d'un objet. Cela
    correspond un peu à ce qu'on déclare dans une classe en POO.

    Ce qui est intéressant avec javascript c'est que tu peux le modifier dynamiquement en cours d'exécution. Ceci pour ajouter des fonctionnalités
    aux objets existants.

    Voici un exemple:

    Si tu veux compter le nombre de caractères présents dans une chaine
    alors en programmation "classique" on ferait une fonction du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    function countChars(chaine, chars) {
      ...
    }
    A l'usage on écrit countChars(une_chaine, '-') pour compter le nombre
    de tirets dans la chaine.

    En POO on étendrait l'objet String de base, genre MyString extend String
    et on y ajoute la méthode countChars.

    Mais la méthode countChars n'est disponible que pour les instances de
    MyString (bouhhh que c'est pauvre la POO classique :-)

    En javascript, on étend directement l'objet String pour que toutes les
    String dispose de la fonctionnalité voulue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    String.prototype.countChars = function(chars) {
    	var n=0;
    	for(var i=0;i<this.length;i++) {
    		if(chars.indexOf(this.charAt(i))!=-1) n++;
    	}
    	return n;
    }
    A l'usage c'est souvent bien pratique, on peut écrire des choses
    du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    // compte les voyelles d'une constante chaine
    alert('Bonjour je suis un texte'.countChars('aeiouy'));
     
    ou
     
    // compte les slash de l'url courrant
    alert(document.location.href.countChars('/'));
    ça vaut vraiment la peine de s'y intéresser. ça permet d'écrire du code
    souvent bien plus compact.

  11. #11
    Membre averti Avatar de magnus2005
    Profil pro
    Ingenieur SI
    Inscrit en
    Avril 2005
    Messages
    454
    Détails du profil
    Informations personnelles :
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingenieur SI

    Informations forums :
    Inscription : Avril 2005
    Messages : 454
    Points : 331
    Points
    331
    Par défaut
    Le modele javascript est pratique pour du code tres court.
    Par contre ça devient nettement plus difficile à maintenir sur des applications avec beaucoup de code puisqu il devient tres difficile de savoir avec quel object on travaille. Vu que maintenent on fait des appli massive avev AJAX c est devenu assez contraingnant pour la qualité du code
    Mais bon il faut faire avec

    Bien conscient du probleme les auteurs travaillent dessus :

    Doc sur le future javascript 2.0
    par les auteurs de javascript (Ex Netscape)

    http://www.mozilla.org/js/language/j...otivation.html
    Il y a de l espoir pour que ça s ameliore.
    Mais a mon avis se sera massivement utilisable pas avant 2011 pour des appli professionels (si rien ne remplace le javascript d ici la).
    En attendant il faut bien comprendre le modele actuel (qui est tres eloigne de java).

    Perso j essaie de garder toujours la même syntaxe avec prototype
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    myclass.prototype.getString =function(){};
    En fait le moteur javascript du browser ajoute un element au tableau
    myclass et cette element sera une fonction.
    Du coup on peut tripatouiller et faire de la pseudo reflexion sur un object de myclass
    de memoire cela doit être equivalent à ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    myclass["getString"]= function(){};
    LE probleme principale avec javascript :
    C est plus le code est propre plus il est long
    plus il est long plus le runtime est lent
    et plus le temp de chargement est lent

    L avantage : (Ultime)
    Tous les browers recent l implemente à peu pres


    Bon courage

  12. #12
    Membre émérite Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Points : 2 273
    Points
    2 273
    Par défaut
    Effectivement c'est excellent !
    Merci pour les infos

  13. #13
    Membre expérimenté Avatar de julien.63
    Profil pro
    balayeur
    Inscrit en
    Décembre 2005
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : balayeur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 1 348
    Points : 1 311
    Points
    1 311
    Par défaut
    merci pour vos réponses

  14. #14
    Futur Membre du Club
    Inscrit en
    Mars 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 7
    Points : 6
    Points
    6
    Par défaut merci
    ce post repond tres precisement a ma question: merci :-)

    grace a la belle extension Function.bind() de marcha je peux dorenavant ecrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
                anchorElements[i].addEventListener("click", this.openAll.bind(this), false);
    directement dans une methode de mon objet.

    merci merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/12/2006, 16h14
  2. Réponses: 3
    Dernier message: 05/10/2006, 18h52
  3. [POO] Appeler une méthode redéfinie de la classe parente
    Par Djakisback dans le forum Langage
    Réponses: 5
    Dernier message: 04/08/2006, 22h56
  4. [POO]Appelé une méthode d'une classe mère
    Par LE NEINDRE dans le forum Langage
    Réponses: 2
    Dernier message: 14/12/2005, 14h44
  5. [POO] Redéfinir une méthode en se servant de l'ancien code
    Par bart64 dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 31/05/2005, 13h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo