Rails, Ajax et éditeur de cartes - Version imprimable +- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org) +-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38) +--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51) +--- Sujet : Rails, Ajax et éditeur de cartes (/showthread.php?tid=5157) |
Rails, Ajax et éditeur de cartes - popayan - 09-09-2010 Salut à tous, J'aurais besoin de conseil sur un problème liant rails, ajax et une base de données. J'affiche un tableau contenant des images, le type de l'image affiché dépend d'une donnée en base. Chaque cellule est ajoutées à ma liste d'objet Droppable. A coté, j'ai une seconde liste d'image Draggable. Le but étant de déposer une de ces images dans le tableau, mettre a jour ma base de données et rafraichir le tableau ensuite. Pour le moment, j'ai réussi à faire ca en javascript sans ajax (c'est à dire que le réaffichage se fait après rechargement de la page). Voici un peu de code: le code pour créer les éléments droppables Code : <script type="text/javascript"> Code : def receive_drop le reste du code est assez trivial. Donc je me pose la question de savoir qu'est ce que je dois modifier pour ne plus à avoir à rafraichir l'affichage? Si vous avez besoin d'autres morceaux de code, demandez moi. Si vous trouvez le code bancal, n'hésitez pas, j'aime beaucoup la critique RE: Rails, Ajax et base de données - niahoo - 09-09-2010 heu... mais tu connais le principe AJAX ou non ? Pasque si c'est non, commences par comprendre comment ça marche. et si c'est oui, ben tu remplaces "" window.location = '../maps/receive_drop?tile_id='+ tile_id+'&type_id='+ type_id; "" par "" appel de la fonction qui enregistre (); appel de la fonction qui affiche (); "" RE: Rails, Ajax et base de données - popayan - 09-09-2010 oui, ajax, je connais le principe Par rapport à ton commentaire, je peux dire que la "fonction qui enregistre" est déjà faite, c'est la fonction receive_drop. Par contre, je n'arrive pas à lier ca avec ajax et faire la "fonction qui affiche". En gros je veux remplacer le "window.location" par autre chose mais je ne trouve pas quoi... RE: Rails, Ajax et base de données - Sephi-Chan - 09-09-2010 Donc ce n'est pas vraiment lié à Ruby on Rails, mais plutôt à Javascript. Quelle est la librairie Javascript que tu utilises (on dirait bien du Prototype) ? Déjà, si tu fais de l'Ajax, tu n'as pas à te poser la question du rechargement puisque la case déplacé via Javascript sera placé au bon endroit (puisque c'est son placement à cet endroit qui entraînera l'appel asynchrone qui modifiera effectivement la ressource en base de données). J'ai tout de même quelques conseils à te donner vis à vis du contrôleur et de l'action à utiliser. De ce que je comprends, tu as un éditeur de carte avec des tuiles déjà présente, et tu veux changer la tuile quand on dépose une tuile (prélevé sur une palette) sur la tuile existante. C'est bien ça ? Si oui, la tuile par défaut est-elle enregistrée en base de données ? Sephi-Chan RE: Rails, Ajax et base de données - popayan - 09-09-2010 oui c'est prototype. le lien avec ror est sur le fait que je n'ai pas trouvé comment faire ca correctement: j'ai bien trouvé des choses sur ce sujet ( ici, j'ai essayé de m'inspirer de la partie 4.2.2.2 ) mais pas moyen de reprendre ca dans mon code... edit suite à la question de sephi: oui, la map est créé en base avec une tuile par défaut (représentant de l'eau si tu veux tout savoir ) RE: Rails, Ajax et base de données - Sephi-Chan - 09-09-2010 D'accord. Donc ton drag'n'drop devra plutôt déclencher l'action update du contrôleur tiles. Je précise que le code qui vient n'est pas testé, c'est écrit à la volée. Donc à toi de l'adapter si besoin. Donc, admettons qu'on est dans l'action edit du contrôleur maps (puisque c'est la page pour éditer une carte. Notre action devrait donc être à peu près comme ça :
Sur chaque élément du DOM qui représente une tuile, ajoute un attributs pour l'URL de modification. Exemple avec Haml (que je te conseille vivement si tu ne l'utilise pas déjà), tu auras donc une vue maps/edit.html.haml contenant quelque chose comme :
Il te faudra une vue partielle : crée un fichier _tile.html.haml dans le répertoire app/views/tiles/tile avec le contenu suivant :
Jusque là, très simple, le code HTML de chaque tuile aura cette tronche :
Et chaque outil ressemblera à :
Voilà pour le HTML : la carte et la palette. Pour le Javascript, tu auras un code de ce genre :
Ainsi, les outils sont draggable (on peut les déplacer), et les tuiles sont droppable (elles peuvent recevoir des éléments draggable). Quand on relâche un outil sur une tuile, la méthode onDrop est appelée, on récupère l'URL spécifiée sur la balise de la tuile ainsi que le type de terrain de l'outil. On construit également un hash de paramètres Rails ready Ensuite, on effectue la requête Ajax. Elle utilisera la méthode PUT puisqu'on va chercher à modifier une tuile existante. On ajoute .js à l'URL pour préciser à Rails que c'est de l'Ajax. Normalement, il gère bien sans d'autant que Prototype est très fidèle aux conventions de Rails, mais n'en étant pas sûr je préfère être bullet-proof. La vue qui sera rendu par l'appel à l'action demandée (tiles#update, en l'occurrence) devra rendre du Javascript, qui sera interprété comme tel.
Ensuite, on crée la vue pour cette action (app/views/tiles/update.js.haml) et on y place le code suivant.
Là aussi c'est plutôt simple, on génère le HTML pour notre nouvelle tuile, on l'échappe pour Javascript puis on le place dans une variable Ruby html_for_tile. Ensuite, on génère la partie Javascript de notre vue (puisque rappelons-nous que le texte qui sera produit par notre vu sera utilisé en guise de réponse à la requête asynchrone et interprété comme du Javascript) dans un bloc :plain pour que seules les expression de la forme #{expression} soient interprétées par Ruby. Et voilà, on a notre éditeur de carte ! Sephi-Chan RE: Rails, Ajax et base de données - popayan - 09-09-2010 Déjà merci beaucoup pour le temps passé sur mon problème, ca fait plaisir ^^ J'ai commencé à étudier tout ça, je pense que ca va répondre exactement à mes besoins. Une question tout de même concernant un bout de code: Code : .tile{ :id => "tile-#{tile.id}", Si je comprends bien, ce bout de code créé une div avec 4 attributs mais il n'affiche rien? j'essaie également d'écrire la route map_tile_path dans mon fichier de routes.rb, je pense que j'en suis pas loin, mais c'est pas encore ca :p RE: Rails, Ajax et base de données - Sephi-Chan - 09-09-2010 Le fragment de code Haml est interprété (pour peu que ta vue s'appelle machin.truc.haml, qui indique à Ruby que cette vue doit être interprétée avec Haml (alors que les vues machin.truc.erb sont interprétées par le moteur Erb) est produit du HTML (qui a la particularité d'être parfait aussi bien en terme de validité que de rendu à l'indentation). Ici, on met ça dans une vue partielle, qu'on différencie d'une vue classique par son nom préfixé d'un underscore et qu'on invoque grâce à la méthode render. On fait ceci afin de pouvoir réutiliser cette vue partielle plus tard, notamment dans la vue de l'action, pour éviter de dupliquer du code bêtement : si le HTML d'une tuile change, il suffit de modifier la vue partielle. Pour les routes, il faut définir une ressource maps qui dispose de ressources tiles afin de générer les 7 routes pour les maps et les 7 routes pour les tuiles.
Sephi-Chan RE: Rails, Ajax et base de données - niahoo - 09-09-2010 non, ça c'est une fonction qui enregistre : Code : new Ajax.Request(tileUrl, { Tout ce que je vois qui s'appelle receive_drop dans ton code c'est dans une URL. Je suppose donc que tu me parlais d'une fonction PHP. C'est pour ça que je te demandais si tu avais bien saisi le principe, car à aucun moment tu ne faisais d'envoi de données.. Bon par contre je connais mal prototype donc je ne vois pas à quel moment on récup les données Sephi dans ton js. RE: Rails, Ajax et base de données - popayan - 09-09-2010 (09-09-2010, 03:54 PM)Sephi-Chan a écrit : Le fragment de code Haml est interprété (pour peu que ta vue s'appelle machin.truc.haml, qui indique à Ruby que cette vue doit être interprétée avec Haml (alors que les vues machin.truc.erb sont interprétées par le moteur Erb) est produit du HTML (qui a la particularité d'être parfait aussi bien en terme de validité que de rendu à l'indentation). J'ai dû mal poser ma question... j'ai bien compris le principe. La question était que la <div> a bien des attributs mais son contenu est vide? voici le code que ca génère: Code : <div class='map' id='map-1'> |