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 :

Retrouver l'index d'un objet placé dans un array


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Par défaut Retrouver l'index d'un objet placé dans un array
    Bonjour,

    * J'ai une liste d'ID (un par client) et à chaque client est associé plusieurs marqueurs sur une carte leaflet.

    * Je parcours la base de donnée, trouve quel est le plus grand ID, et crée une markerMap (tableau à 2 dimensions) où je pourrai associer IDs et marqueurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var markerMap = new Array( <?php include('get_maxId.php');?> ); // pour les IDs des clients
    for (i=0;i<markerMap.length;i++)
    	{
    	markerMap[i] = new Array(); // ici on mettra les IDs des marqueurs de chaque client (nombre indéterminé)
    };
    * Ensuite je récupère en base de données le nombre d'IDs et le nombre de marqueurs associés à chaque ID (qui est variable d'un client à l'autre) et fais 2 boucles imbriquées pour parcourir les IDs et leurs marqueurs associés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    //php pour récupérer en bdd et qui retourne un objet JSON (accessible ds la boucle via data[i]), puis :
    for (var i = 0; i < data.length; i++) { // boucle sur les IDs
       var combien_marqueurs = data[i].combien_marqueurs;
       var pseudoId = data[i].id;
     
       for (var j = 1; j <= combien_stories; j++) { // boucle sur les marqueurs
       //... 
       }
    }
    *** Mon problème est dans cette 2ème boucle :
    Dans cette boucle, je crée les marqueurs et les rentre dans la markerMap pour pouvoir les manipuler ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval('markerMap[clientId]['+j+'] = marker');
    Tout va bien, le j est bien pris en compte. Mais, ensuite, j'utilise une fonction pour enregistrer la position des marqueurs dans la bdd lorsqu'ils sont déplacés sur la carte (on dragend) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    marker.on('dragend', function(event) {
    	var result = this.getLatLng();
    	var lati = result.lat;
    	var longi = result.lng;
    	$.post('set_position_marqueur.php', { marqueurId: j, latitude: lati, longitude: longi});
    });
    Et là, bien sûr, c'est le drame! Lorsqu'on drag un marqueur la 2ème boucle en j++ est finie depuis longtemps et je ne peux enregistrer en base que le dernier marqueur de chaque utilisateur. Bien sûr ça fonctionne si je met le numéro du marqueur en dur, mais j'aimerai éviter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (j==1){	marker.on('dragend', ... $.post('set_poi.php', { marqueurId: 1, latitude: lati, longitude: longi}); }
    if (j==2){	marker.on('dragend', ... $.post('set_poi.php', { marqueurId: 2, latitude: lati, longitude: longi}); } 3,4,5 etc.
    >>> QUESTION :
    Y a-t-il un moyen de retrouver depuis le marqueur sa place dans la markerMap afin de savoir si on est en train de manipuler le marqueur 1, le 2, le 3... Pour l'id du client, je me sers d'une variable session_id, donc pas de soucis.

    Je voudrais donc juste trouver markerMap[clientId][ça]
    parser le tableau? faire une sorte de tableau reverse (je l'avais fait en flash)? créer une autre var qui stocke la "vraie" valeur de j? ou autre?

    merci bcp!

  2. #2
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Par défaut
    À deux heures du mat' comme ça j'ai peut-être pas tout saisi mais j'ai l'intuition que tu as besoin de indexOf ou lastIndexOf.

    Et puis j'ai vu cette horreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval('markerMap[clientId]['+j+'] = marker');
    Je vois pas l'intérêt du eval ici. Toujours éviter eval quand on peut. Il y a des ressources sur ce site qui expliquent pourquoi, fais une petite recherche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    markerMap[clientId][j] = marker;
    Ça marche pas simplement comme ça ?
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Par défaut
    Merci de t'intéresser à mon problème. A cette heure, on ne voit plus clair

    Effectivement eval ne servait à rien. Je l'avais cru utile en désespoir de cause alors que le problème venait d'ailleurs sûrement. Merci!

    C'est une question de sécurité c'est ça (injection de code) ? Si on ne peut s'en passer mais que les données ne viennent pas d'un champs input, c'est pas trop grave?
    Je fais des appels à la bdd après, mais j'ai fait des requêtes préparées (d'après ce que j'ai lu, ça évite les injections)

    Par ailleurs, merci pour indexOf ça va sûrement le faire! Par contre, je lis que c'est incompatible avec IE < 9...
    Il va peut-être falloir que je code en dur alors...

    Bonne nuit!

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2014
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 24
    Par défaut
    Merci pour indexOf, je ne savais pas que ça marchait pour les tableaux. J'ai fait ça et ça roule :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    marker.on('dragend', function(event) {
    	var result = this.getLatLng();
    	var lati = result.lat;
    	var longi = result.lng;
    	var marqueurId = markerMap[sessionId].indexOf(this); // sessionId = clientId en réalité // >>> OK mais pas sur IE8
    	$.post('set_position_marqueur.php', { marqueurId: marqueurId, latitude: lati, longitude: longi});
    });
    Alors pour IE8, j'ai tout essayé (y compris des boucles dans la boucle etc...), pas moyen de sauvegarder ce j de la boucle qqe part pour le retrouver ensuite... Sinon j'ai trouvé une réécriture de la fonction indexOf pour être compatible IE8, je ne sais pas si ça peut fonctionner.

    Mais j'aurais peut-être dû faire un tableau à base de propriétés?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //A la place de : 
    markerMap[clientId][numéro du marker] = marker
    //Faire : 
    var markerMap[clientId]= [
            {
                'latitudeMarker1':'35.000000',
                'longitudeMarker1': '56.000798',
            },
            {
                'latitudeMarker2':'35.000000',
                'longitudeMarker2': '56.000798',
            }, etc....
    ];
    Aurais-ce été mieux? Sachant que je ne sais pas à l'avance le nombre de clients ni le nombre de markers par client, comment déclarer ça?

  5. #5
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Par défaut
    Le code de remplacement que tu as trouvé sur JDN s'appelle un polyfill. Il y en a un plus efficace et plus robuste sur le MDN.

    Pour eval je pense que tu confonds injections XSS et injections SQL. Ce n'est pas le même champ de bataille (si tu vois ce que je veux dire) : une XSS attaque le visiteur, une injection SQL attaque la base de données.
    Mais pour moi, eval c'est surtout un problème d'efficacité : normalement, tout le code source JavaScript est interprété avant l'exécution ; avec eval, le moteur d'exécution est obligé de rappeler l'interpréteur, ce qui peut causer un ralentissement.

    Le « tableau à base de propriétés » c'est aussi une bonne idée Mais pourquoi pas un objet anonyme tout simplement ? Tu peux le déclarer vide pour commencer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var markerMap[clientId] = {};
    Grâce à ça tu n'as pas besoin de connaître à l'avance le nombre de clients. Et après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    markerMap[clientId].latitudeMarker1 = '35.000000';
    markerMap[clientId].longitudeMarker1 = '56.000798';
    markerMap[clientId].latitudeMarker2 = '35.000000';
    markerMap[clientId].longitudeMarker2 = '56.000798';
    // etc.
    Ou avec la syntaxe des crochets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    markerMap[clientId]["latitudeMarker1"] = '35.000000';
    markerMap[clientId]["longitudeMarker1"] = '56.000798';
    markerMap[clientId]["latitudeMarker2"] = '35.000000';
    markerMap[clientId]["longitudeMarker2"] = '56.000798';
    // etc.
    Cette dernière syntaxe te permet de gérer dynamiquement tes noms de variables : faire des trucs du genre markerMap[clientId]["latitudeMarker" + j].

    Mais l'important c'est d'avoir des structures de données simples et cohérentes. En l'occurence, tu peux décider qu'un marqueur c'est un tableau à deux cases (latitude et longitude), ou alors un objet avec une propriété latitude et une propriété longitude. Et du coup, tu stockes des tableaux de marqueurs, ce qui ressemble donc à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    markerMap[clientId] = [
      ['35.000000', '56.000798'], // marqueur 0
      ['35.000000', '56.000798'], // marqueur 1
    ];
    Ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    markerMap[clientId] = [
      { latitude: '35.000000', longitude: '56.000798' }, // marqueur 0
      { latitude: '35.000000', longitude: '56.000798' }, // marqueur 1
    ];
    Un peu comme tu as fait, mais la différence c'est que les noms de propriétés sont les mêmes ce qui est bien plus pratique !
    Et pour y accéder (suppose que tu as une variable markerId contenant 0 par exemple) :
    • si tu as choisi des tableaux à deux cases, markerMap[clientId][markerId][0] pour la latitude et markerMap[clientId][markerId][1] pour la longitude ;
    • sinon, simplement markerMap[clientId].latitude et markerMap[clientId].longitude.

    Quand j'ai à choisir une représentation de structures comme ici, en général je préfère des noms plutôt que des tableaux. C'est un peu plus long, mais tellement plus lisible
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 207
    Par défaut
    Bonjour,
    peut être n'ai je pas compris ton problème, mais je me risque.
    en utilisant un objet markerMap ={}, à la création des marker on initialise de telle sorte à avoir une liaison à "double sens"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    le_nouveau_marker.clientId = clientId;     // ajout propriété au marker
    le_nouveau_marker.clientIndex = i;         // si vraiment nécessaire
    markerMap[clientId].push( le_nouveau_marker);
    de telle sorte que tu peux obtienir directement sa position, si nécessaire.

    et dans ta fonction plus de soucis de récupération des données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    marker.on('dragend', function(event) {
    	var result = this.getLatLng();
    	var lati   = result.lat;
    	var longi  = result.lng;
    	var client = this.clientId;    
    	var index  = this.clientIdIndex;    
    	// la suite...de ton besoin     
    });

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

Discussions similaires

  1. [2.x] Retrouver l'objet User dans un form de FosUserBundle
    Par DanaKil dans le forum Symfony
    Réponses: 0
    Dernier message: 18/05/2015, 13h30
  2. Agir sur des objets placés dans un tableau
    Par CyrilD dans le forum Général VBA
    Réponses: 2
    Dernier message: 27/03/2011, 22h06
  3. Retrouver l'index d'un(e) Item cliqué dans un ListBox
    Par Claude_Azoulai dans le forum VB.NET
    Réponses: 2
    Dernier message: 01/02/2010, 12h10
  4. [Vb.net] Indexé un objet crée dans une boucle
    Par picpic dans le forum Windows Forms
    Réponses: 10
    Dernier message: 17/12/2003, 14h37
  5. Réponses: 3
    Dernier message: 09/02/2003, 01h09

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