Express.js Voir « » GLOBALS
-
12-10-2019 - |
Question
J'utilise express.js (sur Node.js) et je sais que vous pouvez rendre une vue avec des données personnalisées via le paramètre « population locale ». (res.render("template", { locals: { foo: "bar" } });
)
Est-il possible d'avoir « GLOBALS »? (Ie. Les données qui est accessible à toutes les vues)
J'ai vu view options
, mais ce n'est pas récursif, il remplace les gens du pays que je téléviseur si vous utilisez des habitants avec mon modèle.
Ceci est mon cas d'utilisation: Je veux faire en sorte que les fichiers CSS / JS peut être ajouté sur une base par page, et cela fait partie de ma mise en page principale. Le problème est, si je ne définissez pas explicitement ces tableaux sur tous les rendre, je reçois une erreur non définie, donc dans mon modèle, je dois toujours faire la danse typeof css !== "undefined"
. De plus, j'ai d'autres listes d'options de boîte de sélection que je ne veux pas avoir à ajouter explicitement à chacun de mes formes.
La solution
Il convient de noter pour ceux qui sont venus sur cette question depuis la sortie de Express 3, que la méthode « dynamicHelpers » n'existe plus.
Au lieu de cela, vous pouvez utiliser la fonction app.locals, qui agit comme un objet que vous pouvez stocker des valeurs ou des fonctions, et les rend ensuite à la disposition des points de vue. Par exemple: -
// In your app.js etc.
app.locals.title = "My App";
app.locals({
version: 3,
somefunction: function() {
return "function result";
}
});
// Then in your templates (shown here using a jade template)
=title
=version
=somefunction()
// Will output
My App
3
function result
Si vous avez besoin d'accéder à l'objet de demande d'informations de traction à partir, vous pouvez écrire une simple fonction middle-ware et utiliser la variable app.settings.
Par exemple, si vous utilisez connexion flash pour fournir des messages à vos utilisateurs, vous pourriez faire quelque chose comme ceci:
app.use(function(req, res, next) {
app.set('error', req.flash('error'));
next();
});
Ce qui vous donnera accès au message d'erreur avec = settings.error dans votre modèle.
Ces sujets sont abordés ici, bien que légèrement brièvement: http://expressjs.com/api. html # app.locals
Mise à jour: Express 4
app.locals
est maintenant un objet simple JavaScript, chaque propriété doit être réglé un par un.
app.locals.version = 3;
app.locals.somefunction = function() {
return "function result";
}
res.locals
fournit la fonctionnalité exactement le même, sauf qu'il doit être utilisé pour les données spécifiques à la demande plutôt que des données d'application à l'échelle. Un objet utilisateur ou les paramètres est un cas d'utilisation commune.
res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
backgroundColor: 'fff'
}
Autres conseils
Il y a un moyen d'avoir des variables « globales » pour les vues, en utilisant les aides de vue dynamiques.
A partir du guide express.js:
app.dynamicHelpers (obj)
Registres aide de vue dynamique. les aides de vue dynamiques sont tout simplement fonctions qui acceptent req, res, et sont évalués sur le serveur par exemple avant une vue est rendue. La valeur de retour de cette fonction devient la variable locale, il est associé à.
app.dynamicHelpers ({session: fonction (REQ) {res, retourner req.session; }});
Toutes les vues aurait maintenant la session disponible afin que les données de session peuvent être accédé via session.name etc:
Vous pouvez trouver un exemple concret sur la façon de les utiliser ici: https: // github .com / alessioalex / Nodetuts / arbre / maître / express_samples (noeud app.js pour démarrer l'application)
Un exemple concret d'utiliser les options d'affichage comme l'auteur mentionné:
var app = express.createServer();
app.configure(function() {
app.set('views', path.join(__dirname, '..', 'views'));
app.set('view engine', 'jade');
app.set('view options', {
assetVersion: 1
});
Et puis dans mon layout.jade (modèle de base pour l'application dans mon cas):
link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')
Avec ce petit truc, je ne dispose que de mettre à jour la variable assetVersion
un endroit pour vous assurer que mes actifs ne sont pas mises en cache dans Varnish ou d'autres endroits.
Je liquidée à la recherche dans le code source, et je l'ai effectivement trouvé que cela est désormais possible dans les versions jamais de Express. (Jusqu'à présent, uniquement disponible via GitHub)
La façon d'accomplir la plus simple est de créer une variable qui représente l'ensemble par défaut de la population locale pour votre point de vue. Ensuite, créez une fonction qui accepte un objet, se confond avec la population locale, et renvoie l'objet fusionné.
Je passe également à TOUS mes locaux à l'intérieur d'un objet conteneur à savoir {locals:{g:{prop:val}}}
donc dans mon point de vue, je peux refernce g.prop
qui va juste revenir null
quand il est pas défini, au lieu de lancer une erreur non définie.
function default_page_vars(custom_vars){
var vars = {
footer: true,
host: req.headers.host.split(':')[0],
config: this.config
};
if(custom_vars){
for(var k in custom_vars){
vars[k] = custom_vars[k];
}
}
return {
g:vars
};
}
//within your handler
response.render(view, {
locals: default_page_vars(other_locals)
});
Ceci est une réponse enterrée, mais je finalement mis au travail.
1) Ceci est un exemple autour du module connect-éclair
2) Ajouter un morceau de middleware dans server.js / app.js ajouter req
à locals
. Cela permet au modèle d'appel request.flash()
chaque fois qu'il a besoin. Sans cela, flash()
se consomme sur chaque demande / redirect encontre du but recherché.
var app = module.exports = express()
, flash=require('connect-flash');
app.configure(function(){
...
app.use(express.session({ secret: "shhh" }));
// Start Router
app.use(flash());
app.use(function(req, res, next) {
res.locals.request = req;
next();
});
app.use(app.router);
});
3) Configurez votre itinéraire comme normale (ce qui est coffeescript, mais rien de spécial)
app.get '/home', (req, res) ->
req.flash "info", "this"
res.render "#{__dirname}/views/index"
4) Appel request.flash () lorsque vous voulez que les messages. Ils sont consommés à chaque appel, alors ne les ou ils CONSOLE.LOG ne serai parti: -)
!!!
html
head
title= config.appTitle
include partials/_styles
body
include partials/_scripts
#header
a(href="/logout") Logout CURRENTUSER
h2= config.appTitle
#messages
- var flash = request.flash()
each flashType in ['info','warn','error']
if flash[flashType]
p.flash(class=flashType)
= flash[flashType]
block content
h1 content here
Express 4
Vous pouvez accéder à des variables locales dans les modèles fournis dans l'application.
Donc, si vous voulez utiliser des locaux dans votre template => en supposant que vous avez un moteur de template NPM installé sur votre noeud / application exprimer.
D'abord, vous devez définir les expriment des objets locaux avec votre commande variables dans votre fichier app.js
, vous pouvez utiliser un objet si plusieurs valeurs sont nécessaires (notre cas dans ce post)
/**
* Set locals object
*/
app.locals.layoutData = {
site: {
title: 'MyWebSiteTitle',
},
metaTag: {
charset: 'UTF-8',
description: 'MyDescription',
keywords: 'keyword-1,keyword-2,...',
author: 'MyName',
viewport: 'width=device-width, initial-scale=1.0'
}
};
Ensuite, pour accéder aux valeurs dans le fichier modèle layout.pug
(dans le cas du moteur de modèle PUG par exemple)
doctype html
html
head
//title
title #{locals.layoutData.site.title}
//Describe metadata
meta(charset=layoutData.metaTag.charset)
meta(name='description', content=locals.layoutData.metaTag.description)
meta(name='keywords', content=locals.layoutData.metaTag.keywords)
meta(name='author', content=locals.layoutData.metaTag.author)
meta(name='viewport', content=locals.layoutData.metaTag.viewport)
body
block content
br
hr
footer
p All rights reserved © 2018 | #{locals.layoutData.site.title}
Testé avec
"dependencies": {
"express": "^4.16.3",
"pug": "^2.0.3"
}