Est-ce seulement possible ?
Imaginons une action index d'un Controller Post.
J'aimerai faire 2 requêtes sur l'action index de mon PostController :
- 1 requête classique avec find('all');
- 1 requête ajax et transmettre les résultats en Jquery pour traiter le DOM
Possible ou pas ?
J'explique tout de même pourquoi je veux faire cela :)
1 / ma vue index qui ressort la liste des articles est une page qui sera mise en cache car j'ai activé le helper cache.
2/ Néanmoins j'ai besoin de traiter dynamiquement chacun des articles et leur ajouter ou non une div selon que l'internaute aura ajouté cet article à ses favoris ou non.
Le syteme de favoris est opérationnel et fonctionne, je voudrai donc maintenant afficher un élément visuel sur chaque article (une div) afin d'indiquer à l'utilisateur que tel ou tel article est dans ses favoris ou pas.
Pour cela, j'ai besoin de traiter le dom en jQuery puisque la page index est mise en cache.
Voila/ Soirée arrachage de cheveux :)
Vu que ta page est en cache, tu ne pourras pas faire ce que tu souhaites côté serveur. Ton serveur te renvoie une page au format html lorsque tu fais une requête Get. C'est cette page html qui est mise en cache justement. Tu ne pourras donc pas faire d'autres opération côté serveur pour cette page. Tu peux quand même réaliser ce que tu souhaites depuis 2 moyens :
Utiliser la balise nocache de CakePHP qui va te permettre d'afficher des informations à jour depuis une page mise en cache
Faire un appel AJAX et modifier le DOM au chargement de la page.
Merci. J'ai bien évolué sur la question ;) J'ai bossé quoi :) LE no cache est une solution effectivement. Cependant, je pense que je vais traiter le truc en jQuery directement sur le dom.
Sinon pour le systeme de favoris, je crois que j'ai exploré toutes les solutions, et j'ai finalement opter pour celle qui fait souffrir le moins la bdd en terme de nombre de requetes...
Solution 1 : J'étais parti sur une requete systématique de la table des favoris à chaque fois que l'utilisateur appelait la page qui liste les articles.
Solution 2: Je me suis dit "pourquoi ne pas stocker les favoris dans un cookie sur le pc du client ? " BOn systeme sauf que ca nécessitait aussi des requetes si l'utilisateur changeait de PC ou s'il a effacé ou désactivé les cookie depuis son navigateur.
Solution 3 (celle que j'ai adopté) : Stocker les favoris dans la session de l'utilisateur.
Avantage : Nombre de requête limitée (une à la connexion de l'utilisateur pour récupérer ses favoris, une si l'utilisateur ajoute un favori, une si il en supprime un). ses favoris étant stockée en session, plus besoin d'autres requetes.
Maintenant, plus qu'à faire passer ces données et traiter la page en jQuery pour créer un "bookmark visuel"
Merci à tout le monde en tout cas ;)
@plus
Salut,
j'aurais fais 2 actions à ta place :
index() : qui fait l'action index comme précité par toi même
fav() : qui permet de récupérer les informations que tu souhaites pour faire la maj.
Tu peux facilement appeler une url Cakephp avec la requete $.get() de jQuery. ex :
$.get("<?php echo $this->Html->url(array('controller' => 'posts', 'action' => 'favs')); ?>", function(data) {
console.log(data); // les resultats retournés par l'action
});
A partir de ces résultats, tu seras capable de faire les modifs dans le DOM comme tu le souhaites.
HS : je te conseille de travailler avec Mustache par exemple, qui simplifie grandement la maj des éléments dans le DOM.
Sur le papier, ça me paraît bien ta solution. Je peux donc selon toi appeler 2 actions sur un clic d'un éléments ?
En l'occurence l'utilisateur clique par exemple sur le bouton "Blog" et je peux appeler 2 actions ? 1 via le chemin classique et l'autre via un appel Ajax en jQuery . Je vais réfléchir à ça, si ça me semble bizarre c'est que je n'ai jamais mis en oeuvre ce genre de concept, mais pourquoi pas :)
Je teste et je fais mon retour d'expérience ^^
Tu peux faire autant de requêtes Get que tu souhaites en AJAX. donc lorsque tu vas cliquer sur le lien "Blog" de ton site, tu vas récupérer la liste des articles (qui est mise en cache si j'ai bien compris). Une fois que ton DOM est chargé, tu peux ensuite faire la requête AJAX $.get comme tu le sens pour récupérer les autres informations que tu souhaites (ici la gestion des favoris). Tu pourras ensuite manipuler le DOM comme tu l'entends.
PS : je ne l'ai pas mis dans mon 1er post mais je pense que le format de données JSON serait pas mal pour cette action AJAX.
Je vais tenter de m'expliquer un peu mieux sur ce qui exsite et la ou je veux aller :)
Ce qui existe
1/ La requête par mon Postcontroller via l'action index existe -> C'est elle qui me retourne les articles du blog que j'affiche donc dans la vue index.
2/ L'utilisateur peut, via un bouton (requete ajax) ajouter des articles favoris. J'ai ajouté ça dans une nouvelle table posts_users qui comprend comme champs : id | user_id | post_id (chaque id utilisateur à 1 ou plusieurs posts)
Ce que je cherche à faire : indiquer à l'utilisateur dans la liste des articles, quels articles sont dans ses favoris.
Alors sans cache, pas de probleme, je suis parvenu à mes fins de cette façon :
Dans l'action index de mon PostController j'ai ajouté une requête de type find('list) sur le champs post_id de ma table posts-users.
J'ai en résultat un array
Et dans la vue index où je faisais déjà une boucle foreach pour lister les articles, j'ai ajouté à l'intérieur de l'article une condition qui ajoute une div, seulement si l'id du post est dans l'array retourné par ma requête. En clair ça donne ça :
Ma requête supplémentaire dans le PostController action index (en plus de la requete classique qui liste les post :
$user_id = $this->Auth->user('id');
$this->loadModel('PostUser');
$this->PostUser->recursive = -1 ;
$d'favoris'] = $this->PostUser->find('list', array(
'conditions' => array('PostUser.user_id' => $user_id),
'fields' => array('PostUser.post_id'),
'order' => array('PostUser.post_id DESC')
));
Avec cette requete je récupère un aray ( $favoris ) qui liste les post_id de l'utilisateur en cours (ses favoris):
array
(int) 209 => '21',
(int) 207 => '15',
(int) 206 => '8'
)
De là, dans ma vue index, je rajoute une condition (à l'intérieur de ma boucle foreach qui affiche les articles) afin d'afficher ou non une indication visuelle qui indiquera à l'utilisateur que tel ou tel article est dans ses favoris. Je procède avec une simple condition et la fonction php in_array();
<?php if (in_array($posts'id'], $favoris)): echo "Article déjà dans tes favoris"; endif; ?>
Alors sans cache no probleme puisqu' à chaque appel de l'action index du controller post, le code php est exécuté, donc la boucle foreach qui liste les articles et à l'intérieur, ma petite condition qui affiche ou non "déjà dans tes favoris".
Là ou ca se complique, c'est qu'en intégrant un cache sur cette vue index. Inévitablement c'est le cache qui est servi, donc du HTML et ma condition à l'intérieur de la boucle foreach ne sert plus à rien, d'ou mon option de traiter cela en aval, c'est à dire apres que la page HTML soit servie et en agissant en jQuery sur le DOM.
Le clic sur le menu "Blog par l'utilisateur" devrait donc appeler en meme temps la vue index en cache et une action ajax qui me retournerai mon array précemment cité,
array
(int) 209 => '21',
(int) 207 => '15',
(int) 206 => '8'
)
(Sous forme de Json je te l'accorde :) )
afin de le traiter en jquery apres l'affichage de la page.
C'est la seule solution que j'ai en tête... Si une autre solution moins tordue existe pour pallier à cette contrainte je suis preneur :)
Et si je peux appeler à la fois lors d'un seul clic l'action index et une autre action ajax qui me retournerai mon array (fav par exemple) alors ça pourrait effectivement fonctionner. :)
Un peu long, je ne sais pas si je suis clair dans la démonstration :)
En tout cas merci de tes réponses qui m'ont déjà un peu plus éclairé :)
Je pense que la 1ère solution devrait fonctionner. Tu peux facilement la tester en tout cas :
http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html#marking-non-cached-content-in-views