11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour
Je n'arrive pas à faire un callback sur une méthode dans une classe. Sur le code suivant, très simplifié, j'ai une classe "Node" pour un noeud de liste, une classe "List" pour la liste à simple chainage. Je désire ranger dans cette liste des objets "Point2D" ayant chacun deux cotes x et y. Le programme principal montre l'empilement dans la liste de deux points, de cotes (10, 10) et (20, 20). Jusque là tout va bien. Maintenant, je voudrais programmer un "iterateur" sur ma liste qui la parcourt et appelle une méthode particulière. J'ai donné comme exemple la méthode "translate (dx, dy)" qui décale tous les points de la même quantité. Bien sur je peux dans mon code principal programmer une boucle qui parcourt la liste et effectue l'appel à "translate", mais je voudrais faire plus court et plus joli en appelant un itérateur auquel je passe en paramètre d'une fonction "callback". Et là, ça ne va plus. Je n'y arrive pas. J'ai du mal à trouver dans la littérature comment faire. Faire un appel à "bind" ? Oui mais comment faire dans le détail ? Si quelqu'un qui connait l'astuce peut aider...


<!DOCTYPE html>
<html lang="fr" >
<head><meta charset="utf-8"></head>
<body>
<script>
// L'objet NodeList : noeud de liste 
// Noeud de liste
class NodeList {
    constructor (objetLie) {
        this.objetLie = objetLie ;
        this.lienAvant = null ;
    }
}

// Liste à simple chainage
class List {
    constructor () {
        this.premier = null ;
    }
    addFirst (objet) {
        var noeud = new NodeList (objet) ;
         if (this.premier == null) this.premier = noeud ;
        else {
            noeud.lienAvant = this.premier ;
            this.premier = noeud ;
        }
    }
    iterate (callBackFunction, p1, p2) {
        // Un itérateur avec callback paramétrable
        var noeud = this.premier ;
        while (noeud != null) {
            var quoi = noeud.objetLie ;
            // quoi.callBackFunction = callBackFunction ; // ne marche pas
            //callBackFunction.bind (quoi) ; // ne marche pas
            quoi.callBackFunction (p1, p2) ; // ne marche pas
            noeud = noeud.lienAvant ;
        }
    }
}

class Point2D {
    constructor (x, y) {
        this.x = x ; this.y = y ;
    }
    translate (dx, dy) {
        this.x += dx ; this.y += dy ;
    }
    dump () {
        alert ("point : " + this.x + ", " + this.y) ;
    }
}

var liste = new List () ;
liste.addFirst (new Point2D (10, 10)) ;
liste.addFirst (new Point2D (20, 20)) ;
// A partir de là, ça ne fonctionne plus !
liste.iterate (dump) ;
liste.iterate (translate, 5, 5) ; 
liste.iterate (dump) ;
</script>
</body>
</html>

Modifié par JiPe38 (23 May 2021 - 15:08)
Modérateur
Hello,

JiPe38 a écrit :

je voudrais programmer un "iterateur"


Je ne vois pas l'intérêt puisque tu parcours un simple array. D'ailleurs ton itérator est faux.
1. ça doit être dans une class séparée (Comme ça, tu peux t'en resservir Smiley cligne ). Règle suprême en POO => une class = un rôle
2. Je ne vois pas de méthod reset/rewind
3. je ne vois pas d'attribut index
4. je ne vois pas de méthod next
5. je ne vois pas de méthod current
6. (optionel) je ne vois pas de méthode :
6.1 : prev
6.2 : hasMore
6.3: add


JiPe38 a écrit :

auquel je passe en paramètre d'une fonction "callback". Et là, ça ne va plus. Je n'y arrive pas.


Je n'ai pas testé ton code. Mais Je pense que tu essaies de faire ce genre de chose (bien que ce ne soit pas adéquate, j'ai laissé le nom de ta méthode):

class List {
    //....
    iterate (callBackFunction) {
        // Un itérateur avec callback paramétrable
        var noeud = this.premier ;
        while (noeud != null) {
            var quoi = noeud.objetLie ;
            // quoi.callBackFunction = callBackFunction ; // ne marche pas
            //callBackFunction.bind (quoi) ; // ne marche pas
            callBackFunction(p1, p2) ; // ne marche pas
            noeud = noeud.lienAvant ;
        }
    }
}
// ....
liste.iterate ((5,5)=>{
    //ton code
}) ; 


ps :
- Ce n'est peut être pas une bonne idée de nommée une class NodeList
- Pas de code commenté pour les méthodes Smiley nono
Modifié par niuxe (23 May 2021 - 22:48)
Toujours en retard sur ce coup : l'avertissement par email du message ne fonctionne pas, pourtant je pensais l'avoir paramétré. Merci pour les conseils sur les règles de la POO, mais je me suis permis de faire un peu "borderline" pour raccourcir mon exemple.

1 - C'est un simple exemple, car mon code fait plusieurs milliers d'instructions et je ne vais pas le copier ici. Dans la réalité c'est une liste à double chainage inverse, voire une structure arborescente en listes de listes.
2 à 6 : OK admettons que le mot "iterateur", avec les méthodes habituelles, est mal choisi pour exprimer mon besoin.

Je reformule. J'ai des listes, dont le type donné en exemple est très simplifié, que je désire parcourir sur tous les éléments (avec éventuellement un break dans la boucle), et sur chaque élément de la liste (pointé par "objetLie" à partir d'un noeud, je veux appeler une méthode propre à cet élément. Je le fais actuellement en écrivant des méthodes, dans une classe qui hérite de "liste" :


faireUnTrucSurTousLesElements (paramètre) {
    var noeud = this.premier ;
    while (noeud != null) {
        var objet = noeud.objetLie ;
        objet.faireUnTruc (parametre) ;
        noeud = noeud.lienAvant ;
    }
}

Cette écriture fonctionne, mais avec une bonne trentaine de méthodes sur ces objets, ça alourdit la lecture du code. J'aimerais remplacer les 8 lignes ci-dessus par :


itererSurLaListe (faireUnTruc, parametre) ;


En supposant bien sur que je n'ai qu'une seule déclaration de la méthode "itererSurLaListe" de l'objet "liste". Je sais le faire hors POO et classes, mais à partir du moment ou le callback faireUnTruc est une méthode (polymorphe ou non), je n'y arrive pas. Dans les dernières lignes de la réponse donnée ci-dessus, il faudrait que j'arrive à passer l'adresse de la méthode callback en paramètre.
Modifié par JiPe38 (27 May 2021 - 12:02)