Bonjour à tous,

Je bosse sur un projet ou j'utilise Symfony2 et AngularJS.
Je ne fais rien de bien compliqué avec Angular. En gros, je récupère des données (une liste de contacts) en json et j'affiche une liste.

<ul ng-repeat="contact in contacts">
    // ...
</ul>

Le problème se présente lorsque je veux générer un lien à l'intérieur de cette boucle. En effet, je ne peux pas faire ça puisque twig ne peux pas fonctionner à l'intérieur d'AngularJS.

// lien cool mais seulement côté serveur
<a href="{{ path('app_app_contact_edit', { 'id': contact.id }) }}" Edit</a>

Ma solution, pour l'instant, est de mettre le lien en dur, ce qui est particulièrement moche ...

// lien moche mais qui fonctionne côté client
<a href="http://localhost:8000/contacts/edit/{[{ contact.id }]}"Edit</a>

Vous vous en doutez, ce que j'aimerais faire c'est générer mon lien à l'intérieur du JS, et ça, sans avoir à tout casser.

J'ai entendu parlé de FOSJsRoutingBundle qui semble répondre à mes attentes. Cependant, après l'installation je ne saisie pas très bien le fonctionnement ... Et pas moyen de trouver un exemple complet.

Donc, si quelqu'un veut bien m'orienter sur mes recherches, me donner un exemple que je puisse adapté à mon besoin, ou tout autres choses qui puisse me faire avancer, il est le bienvenue :D

7 réponses


SimonAndGarfunkel
Réponse acceptée

Salut mansaychai,

j'ai déjà eu ce genre de problème et j'ai utilisé le FOSJsRoutingBundle. Je ne sais pas où tu bloques avec ce bundle mais voici la marche à suivre:

  • ajouter la dépendance "friendsofsymfony/jsrouting-bundle" dans ton fichier composer.json et lancer la commande composer update
  • enregistrer le bundle dans le kernel symfony en ajoutant "new FOS\JsRoutingBundle\FOSJsRoutingBundle()" dans app/AppKernel.php
  • ajouter la définition des routes dans app/config/routing.yml
  • éxécuter la commande "php app/console assets:install --symlink web" : ce point peut poser problème si tu développes sur Windows
  • charger les 2 scripts js dans ta vue (vérifie que le navigateur a bien trouvé ces 2 fichiers)

Tu dois désormé avoir accès à la fonction javascript:

Routing.generate('ta_route', {'attr1': foo, 'attr2': bar});

Les routes doivent être définies avec un attribut "options" à "expose: true" pour pouvoir être générées.

Autre idée : dans ton cas, si tu n'as pas envie de charger un bundle, tu peux aussi générer tes routes côté serveur, au moment de la génération du JSON.

++

Bonjour SimonAndGarfunkel,

Très bonne idée de générer les routes en amont, je n'y avais pas pensé !

Merci pour ta réponse très détaillée concernant FosJSRoutingBundle. J'avais oublié l'option 'expose' , alors c'était mal parti !

Grace à toi, je ne suis plus très loin d'avoir débrouillé mon problème. J'ai un dernière petit souci ...
Dans un foreach comme dans mon cas, comment est ce que tu ferais, dans le template, pour générer l'id du contact (qui change à chaque ligne donc) ?

Pour l'instant j'ai fait quelque chose comme ça, mais évidement je ne récupère pas l'id de mon contact :

<td><a href="" id="view">View</a></td>
<script>
    var url = Routing.generate('app_admin_user_view');
    $('#view').attr('href', url);
</script>

Comment t'y es-tu pris ?

J'imagine que lorsque tu dis "générer l'id du contact", tu souhaites en fait récupérer l'id du contact...
Quelle est la structure du JSON que tu récupères ?
Pour ma part, je metterai pour chaque contact une clef 'id' avec sa valeur... je vois pas trop où tu bloques ??

Oui oui je veux bien récupérer l'id du contact c'est ça.
Je galère parce que je dois jongler entre angular et du js classique. J'ai une boucle angular pour afficher les lignes du tableau et intéragir avec. Puis, une boucle pour générer mes liens.

Pour l'instant j'en suis là mais je ne récupère que le dernier id de la boucle pour chaque contact, ma boucle est mal foutue en somme.

        <tr ng-repeat="contact in contacts">
                    <td id="view"></td>
                    <script>
                        var contacts = {{ contacts|raw }};
                        for(var i = 0 ; i < contacts.length ; i++){
                            var view = Routing.generate('app_app_contact_view', { 'id': contacts[i].id });
                            document.getElementById("view").innerHTML = "<a href=" + view + " >View</a>"
                        }
                    </script>
        </tr>

Et ton tableau de contacts est correct ? Ça donne quoi {{ dump(contacts) }} ?

Oui mon json est nickel. Ce qui me perturbe, c'est que si je fais un console.log(contact.id) dans mon for je récupère bien les bonnes données ...

Autre truc :

document.getElementById("view").innerHTML = "<a href=" + view + " >View</a>"

Si je ne me trompe pas, tu ne fais que remplacer le contenu à chaque itération de ta boucle...