Curieux si je le fais bien et si pas comment vous le feriez.
J'ai un modèle Jade qui doit restituer certaines données extraites d'une base de données MongoDB et je dois également avoir accès à ces données dans un fichier JavaScript côté client.
J'utilise Express.js et envoie les données au modèle Jade comme suit:
var myMongoDbObject = {name : 'stephen'};
res.render('home', { locals: { data : myMongoDbObject } });
Puis à l'intérieur de home.jade je peux faire des choses comme:
p Hello #{data.name}!
Qui écrit:
Hello stephen!
Maintenant, ce que je veux, c'est aussi avoir accès à cet objet de données à l'intérieur d'un fichier JS côté client afin de pouvoir manipuler l'objet par un clic de bouton avant de le poster au serveur pour mettre à jour la base de données.
Pour ce faire, j'ai enregistré l'objet "data" dans un champ de saisie masqué du modèle Jade, puis extrait la valeur de ce champ dans mon fichier JS côté client.
Inside home.jade
- local_data = JSON.stringify(data) // data coming in from Express.js
input(type='hidden', value=local_data)#myLocalDataObj
Ensuite, dans mon fichier JS côté client, je peux accéder à local_data comme ceci:
Inside myLocalFile.js
var localObj = JSON.parse($("#myLocalDataObj").val());
console.log(localObj.name);
Cependant, cette entreprise de stringify/parsing semble désordonnée. Je sais que je peux lier les valeurs de mon objet de données aux objets DOM de mon modèle Jade, puis les récupérer à l’aide de jQuery, mais j’aimerais avoir accès à l’objet qui revient d’Express dans JS côté client.
Ma solution est-elle optimale, comment voulez-vous y arriver?
Lorsque le rendu est terminé, seul le code HTML rendu est envoyé au client. Par conséquent, aucune variable ne sera plus disponible. Au lieu d’écrire l’objet dans l’élément d’entrée, l’objet est restitué en JavaScript:
script(type='text/javascript').
var local_data =!{JSON.stringify(data)}
EDIT: Apparemment, Jade nécessite un point après la première parenthèse fermante.
Je le fais un peu différemment. Dans mon contoller je fais ceci:
res.render('search-directory', {
title: 'My Title',
place_urls: JSON.stringify(placeUrls),
});
Et puis dans le javascript dans mon fichier jade je l'utilise comme ceci:
var placeUrls = !{place_urls};
Dans cet exemple, il est utilisé pour le plugin type = === de Twitter bootstrap. Vous pouvez ensuite utiliser quelque chose comme ceci pour l'analyser si vous devez:
jQuery.parseJSON( placeUrls );
Notez également que vous pouvez omettre les sections locales: {}.
Utilisation de modèles Jade:
Si vous insérez l'extrait de code @Amberlamps au-dessus d'un fichier HTML statique inclus, n'oubliez pas de spécifier !!! 5 en haut pour éviter que votre style ne soit brisé, dans views/index. jade:
!!! 5
script(type='text/javascript')
var local_data =!{JSON.stringify(data)}
include ../www/index.html
Cela transmettra votre variable local_data avant le chargement de la page HTML statique réelle, de sorte que la variable soit disponible globalement dès le début.
Serverside (utilisant le moteur de templates Jade) - server.js:
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.get('/', ensureAuthenticated, function(request, response){
response.render('index', { data: {currentUser: request.user.id} });
});
app.use(express.static(__dirname + '/www'));
Vous n'avez pas besoin de passer les variables locales dans l'appel de rendu, les variables locales sont globales. Dans votre appel de fichier Pug, ne mettez pas d’expression de clé, par exemple #{}
. Il suffit d'utiliser quelque chose comme: base(href=base.url)
où base.url
est app.locals.base = { url:'/' };
Avez-vous entendu parler de socket.io? (http://socket.io/). Un moyen facile d’accéder à l’objet à partir d’express serait d’ouvrir un socket entre node.js et votre javascript. De cette façon, les données peuvent être facilement transmises au côté client, puis facilement manipulées à l'aide de javascript. Le code n'aurait pas besoin d'être beaucoup, simplement un socket.emit()
de node.js et un socket.on()
du client. Je pense que ce serait une solution efficace!