2009-08-25 10 views
2

Je rencontre constamment ce problème lors du développement d'applications AJAX. Disons que je veux que les utilisateurs puissent cliquer sur une icône "drapeau" associée à chaque commentaire sur mon site, ce qui entraîne l'envoi d'une requête AJAX au serveur, demandant que le commentaire soit marqué. J'ai besoin d'associer un identifiant de commentaire au commentaire du côté client afin que la requête AJAX puisse communiquer au serveur le commentaire à signaler.Comment associer des données côté serveur avec des éléments d'interface utilisateur côté client en HTML?

This page explique un certain nombre de façons d'annoter le HTML de cette manière, mais aucune d'elles n'est très satisfaisante. Bien que je puisse simplement utiliser un attribut id ou class pour associer l'identifiant de commentaire au bouton indicateur (par exemple id = "comment_1998221"), ceci échoue avec des données plus complexes qui ne rentrent pas bien dans ces attributs (par exemple des chaînes arbitraires). Y a-t-il une meilleure pratique pour ce genre de chose? Chaque fois que j'ai besoin de faire cela, je me retrouve avec un peu de kludge comme utiliser l'attribut id, un champ de formulaire caché, ou pire encore un span défini pour afficher: none. Les attributs data- * HTML5 semblent être une solution parfaite, mais j'ai vu beaucoup d'animosité à leur égard, ce qui me fait penser que les gens doivent déjà avoir une solution qui leur convient. J'aimerais savoir ce que c'est.

+0

Vous pouvez lire ceci: http://stackoverflow.com/questions/992115/custom-attributes-yay-or-nay/992464 – James

+0

C'est une lecture intéressante, bien que malheureusement toutes les suggestions tombent dans la page que j'ai référencée . Je soupçonne qu'il n'y a pas de bonne réponse, et que la plupart des gens utilisent une combinaison d'attributs de classe et d'id, et d'éléments cachés. – Shawn

Répondre

2

Cette page explique un certain nombre de façons d'annoter le HTML de cette manière, mais aucune d'elles n'est très satisfaisante.

Pourtant, ils sont à peu près tout ce que vous avez. Bien que cette page ne soit pas un très bon résumé, il y a des erreurs et il se méprend sur ce que JavaScript signifie «discret».

Par exemple, il est en fait parfaitement possible de placer un élément de script dans le corps, mais pas directement dans un élément de table. Vous pouvez placer tous les fragments de script au bas de la table, ou placer chaque ligne dans sa propre table, ou même, avec certaines limitations si vous avez l'intention de muter le DOM, à l'intérieur de la ligne en question.

Définir "id =" comment-123 "" puis scanner toutes les lignes avec un identifiant commençant par "comment-" est en effet bon pour votre cas particulier. Pour définir des attributs d'informations supplémentaires non identifiants, vous pouvez utiliser des attributs de données HTML5 ou les hacker dans le nom de classe en utilisant par exemple. "Class =" commentaire type-foo data-bar "". Bien sûr, les ID et les noms de classe ont leurs limites quant aux caractères que vous pouvez utiliser, mais il est possible d'encoder n'importe quelle chaîne dans des chaînes valides. Par exemple, vous pouvez utiliser un encodage de style URL personnalisé pour masquer les caractères non-alphanumériques:

<tr class="greeting-Hello_21_20_E2_98_BA"> 
    ... 
</tr> 

function getClassAttr(el, name) { 
    var prefix= name+'-'; 
    var classes= el.className.split(' '); 
    for (var i= classes.length; i-->0;) { 
     if (classes[i].substring(0, prefix.length)==prefix) { 
      var value= classes[i].substring(prefix.length); 
      return decodeURIComponent(value.split('_').join('%')); 
     } 
    } 
    return null; 
} 

var greeting= getClassAttr(tr, 'greeting'); // "Hello! ☺" 

Vous pouvez même stocker des valeurs non-chaînes complexes de cette manière, en les encodant JavaScript ou chaînes JSON puis les récupérer à l'aide exec (ou JSON.parse si disponible).

Toutefois, si vous mettez quelque chose de non-trivial là-dedans, il devient vite salissant. C'est là que vous préférez les commentaires. Vous pouvez entrer n'importe quoi ici sauf la séquence '-', qui est facilement échappée si elle arrive dans une chaîne.

<table> 
    <tr class="comment"> 
     <td>...</td> 
     <!-- {"id": 123, "user": 456} --> 
    </tr> 
</table> 

function getLastComment(node) { 
    var results= []; 
    for (var i= node.childNodes.length; i-->0;) 
     if (node.childNodes[i]==8) 
      return node.childNodes[i]; 
    return null; 
} 

var user= getLastComment(tr).user; 

Le résumé met en garde contre que cela ne peut être garanti pour fonctionner parce que les parseurs XML peuvent éliminer les commentaires, mais DOM niveau 3 LS parseurs doit les garder par défaut, et tous les navigateurs et la bibliothèque XML majeure le fait jusqu'à présent.

0

jQuery API de données est sympa pour ça.

Supposons que vous ayez le DOM suivant ...

<div class="comment"> 
<a href="#">Flag</a> 
Some text 
</div> 

Ensuite, en supposant que vous chargez également ces éléments par ajax, vous pouvez faire

$(".comment").data('someKey', (any javascript value/object)); 

Puis, plus tard, lors de gestionnaire de clic au drapeau, vous pouvez faire ...

$(".flagSelector").click(function(ev) { 
    var extraData = $(this).closest(".comment").data("someKey"); 
    // use extraData along with your request 
}); 

Si vous générez des commentaires côté serveur et que vous les envoyez avec la page initiale, vous devez déterminer comment initialiser les données. Une façon serait d'avoir des ID uniques pour le commentaire et sur pageload, toujours charger les données personnalisées du serveur par Ajax.

0

Voici comment je ferais ceci:

  • Lors du rendu du côté serveur page, générer le lien de marquer comme un lien normal, de sorte que cela fonctionnerait bien si vous n'avez pas javascript activé .

    <a class="flag_link" href="/comment/123/flag/"><img src="flag.gif" /></a>

  • Ensuite, dans le javascript, ajoutez un événement de clic pour le faire en ajax place. Je vais utiliser jQuery pour mon exemple, mais la même chose n'est pas difficile à faire sans cela.

<script>

 
$('a.flag_link').click(function() { 
    $.get($(this).attr('href'), function() { 
    alert('you flagged this comment'); 
    }); 
}); 

</script>

Bien sûr, vous allez faire quelque chose de plus convivial qu'une alerte pour signaler le succès.

Questions connexes