Page 1 sur 1

[Symfony2] Best practice : route en target ajax (fichier js)

Posté : 30 mars 2012, 17:21
par Calimero
Hello,

Dans une appli sf2, j'ai des appels ajax (jQuery) déportés dans des assets js. En voici un exemple :
<script type="text/javascript">
function getClusters()
{   
    var list_groups = '';
    $('#tabPrecise').html('');

    $.ajax({
               type: "POST",
               url: "/getKwGroupManage",
               async: false,
               success: function(msg)
               {
                   list_groups = eval('{' + msg + '}');
               }
           });

    for (var i in list_groups)
    {
        $('#tabPrecise').append('<tr><td style="padding:5px;" class="liClusterKw" id="' + list_groups[i].id  + '">' + list_groups[i].name  + '</td>'
														      + '<td><input type="checkbox" rel="' + list_groups[i].id  + '" id="' + list_groups[i].id  + '" /></td></tr>');
    }
}

</script>
Je n'aime pas du tout l'url en dur et j'aimerais la remplacer par une génération côté serveur (avec la route qui va bien). Problème : on est dans un asset js (fichier javascript indépendant), donc je n'ai pas de traitement serveur à disposition. Il me semble que je n'ai que deux solutions : soit déplacer cette fonction dans mon template twig (pour bénéficier des tags de génération d'url par routing, mais bof...), soit générer l'url du routing dans mon twig et la récupérer en jQuery (bof aussi), ou d'autres solutions que je ne veux même pas envisager (une nouvelle requête ajax pour résoudre la route côté serveur... lol :lol: )

Quelle est selon vous la meilleure façon (propre, maintenable, accessible, etc) de le faire ? Suis-je forcé de réimporter l'appel ajax dans mon template twig, ou y'a t-il mieux ?

Merci :)

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 31 mars 2012, 08:33
par zeus
Et pourquoi ne pas prendre l'url en paramètre de la fonction ?

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 31 mars 2012, 10:56
par Calimero
Et pourquoi ne pas prendre l'url en paramètre de la fonction ?
En effet, ça pourrait être pas mal. L'ennui est que cette fonction est appelée dans un (énorme) onload lui-même présent dans le même fichier js, ce qui ne ferait que déplacer le problème finalement (on en revient à la même question). Je n'ai pas l'impression que la fonction soit appelée ailleurs mais je n'en suis pas non plus 100% sûr pour le moment (gros module).

Le site sur lequel je travaille a été codé très vite et pas toujours bien, ce qui fait que je me frotte à de nombreuses petites choses comme ça pour lesquelles je fais du refactoring en essayant d'élever la qualité du code. Y'a du boulot :)

En attendant mieux, j'ai opté pour "cacher" l'url dans une balise de la page et la récupérer via jQuery, ce qui se fait déjà ailleurs dans cette appli. A défaut d'être parfait, c'est au moins cohérent. (mais je reste attentif à vos idées, n'hésitez pas).

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 02 avr. 2012, 14:21
par shine-neko
Sinon tu peux jeter un coup d'oeil sur le bundle la https://github.com/FriendsOfSymfony/FOSJsRoutingBundle

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 03 avr. 2012, 16:33
par Calimero
Sinon tu peux jeter un coup d'oeil sur le bundle la https://github.com/FriendsOfSymfony/FOSJsRoutingBundle
Sympathique ce bundle :) Je vais en faire l'essai, merci.

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 09 févr. 2013, 09:31
par skylupo
je sais que ce post date de près d'un an, mais pour donner une autre pistes à d'autres visiteurs qui chercheraient aussi à résoudre ce genre de pb:
écrire ton url dans un fichier de paramètres javascript, ou json, ledit fichier serait généré par ton code php, et chargé par le navigateur.

il suffit ensuite, au moment de ta requète ajax, de lire le paramètre fourni par ce fichier.

si les paramètres de ce fichier évoluent au fil de la navigation, il faut penser à ajouter un timestamp à la fin de l'url qui charge le fichier, pour ne pas que celui-ci soit lu depuis le cache du navigateur

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 14 févr. 2013, 10:21
par Yosh
A priori, la meilleur solution est d'utiliser le FOSJSRouting BUndle...

https://github.com/FriendsOfSymfony/FOS ... E.markdown

Cela rajoute deux fichiers JS, l'un réservé au bundle et un second qui sera généré avec toutes les routes disponibles (via la comamnde php app/console fos:js-routing:dump).

Très simple d'utilisation, via les annotations tu exposes ta route

/**
* @Route ("/foo/{id}/bar", name="my_route_to_expose", options={"expose"=true})
*/

Puis en JS, il te suffit d'appeler la fonction generate:

Routing.generate('my_route_to_expose', { id: 10 });

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 16 févr. 2013, 23:32
par Calimero
@Yosh : l'essayer c'est l'adopter :-) (À la suite de la discussion ci-dessus, on est effectivement partis sur ce bundle qui répondait à tous nos besoins, comme tu l'a montré ci-dessus, et ça fait maintenant pas loin d'un an que ça tourne plutôt bien en production).
si les paramètres de ce fichier évoluent au fil de la navigation, il faut penser à ajouter un timestamp à la fin de l'url qui charge le fichier, pour ne pas que celui-ci soit lu depuis le cache du navigateur
Cette astuce est intéressante également pour FOSJsRoutingBundle, comme on a pu le découvrir chez nous (au fil des développements, vos routes ajax vont évoluer et le rafraichissement du fichier JS par les navigateurs de vos utilisateurs peut poser problème dans certains cas).

Re: [Symfony2] Best practice : route en target ajax (fichier

Posté : 18 févr. 2013, 09:36
par Yosh
Oui mais tout de même un inconvénient majeur quand tu utilise assetic, si tu veux que les routes soit inclus dans les assets, il faut gérer un fichier de route en dev et un pour la prod, le base_url utilise ne ce met pas a jour lors du dump.

Pas vraiment pratique. Mais sinon très bon bundle.

Pour le timestamp jquery le fait tout seul en mettant l'option cache a false pour la méthode ajax.

EDIT: je n'avais pas vu la date du post original ^^