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 "Locaux". (res.render("template", { locals: { foo: "bar" } });
)
Y a-t-il un moyen d'avoir des "globaux"? (c.-à-d. des données accessibles à chaque vue)
Je voyais view options
, mais ce n'est pas récursif, il remplace donc les locaux que je définis si j'utilise des locaux avec mon modèle.
Ceci est mon cas d'utilisation: je veux le faire afin que les fichiers CSS/JS puissent être ajoutés sur une base par page, ce qui fait partie de ma mise en page principale. Le problème est que si je ne fixe pas explicitement ces tableaux sur chaque rendu, je reçois une erreur indéfinie, donc dans mon modèle, je dois toujours faire le typeof css !== "undefined"
Danse. De plus, j'ai d'autres listes d'options Select Box que je ne souhaite pas avoir à ajouter explicitement à chacune de mes formulaires.
Il convient de noter ceux qui ont peut-être rencontré 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 objet que vous pouvez stocker des valeurs ou des fonctions dans, puis les rend disponibles à des vues. 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 la requête pour tirer des informations, vous pouvez écrire une fonction de centrale simple et utiliser la variable App.Settings.
Par exemple, si vous utilisez Connect-Flash pour fournir des messages à vos utilisateurs, vous pouvez faire quelque chose comme ceci:
app.use(function(req, res, next) {
app.set('error', req.flash('error'));
next();
});
Ce qui vous donnerait accès au message d'erreur avec = Paramètres.Error dans votre modèle.
Ces sujets sont couverts ici, bien que légèrement brièvement: http://expressjs.com/api.html#app.locals
app.locals
est maintenant un simple objet JavaScript, de sorte que chaque propriété doit être définie une par une.
app.locals.version = 3;
app.locals.somefunction = function() {
return "function result";
}
res.locals
fournit exactement la même fonctionnalité, sauf qu'il devrait être utilisé pour des données spécifiques à la demande plutôt que des données à l'échelle de l'application. Un objet utilisateur ou des paramètres est un cas d'utilisation commun.
res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
backgroundColor: 'fff'
}
Il existe un moyen d'avoir des variables "globales" pour les vues, à l'aide d'aides de vue dynamiques.
Du guide Express.js:
app.dynamichelpers (obj)
Enregistre les aides de vue dynamique. Les aides d'affichage dynamiques sont simplement des fonctions qui acceptent Req, Res et sont évaluées contre l'instance de serveur avant qu'une vue ne soit rendue. La valeur de retour de cette fonction devient la variable locale qu'elle est associée à.
app.dynamichelpers ({session: fonction (req, res) {retour req.session;}});
Toutes les points de vue auraient désormais une session disponible pour que les données de session soient accessibles via Session.Name, etc.:
Vous pouvez trouver un exemple réel sur la façon de les utiliser ici: https://github.com/alessialex/nodetuts/tree/master/express_samples (nœud app.js pour démarrer l'application)
Un exemple réel d'utilisation des 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 ma mise en page.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 tour, je n'ai que de mettre à jour le assetVersion
variable un endroit pour vous assurer que mes actifs ne sont pas mis en cache en vernis ou dans d'autres endroits.
J'ai chuté en regardant dans le code source et j'ai effectivement constaté que cela est maintenant possible dans Jamais des versions d'Express. (Jusqu'ici, seulement disponible via Github)
Le moyen le plus simple d'accomplir est de créer une variable qui représente l'ensemble par défaut de locaux pour votre point de vue. Ensuite, créez une fonction qui accepte un objet, la fusionne avec les locaux et renvoie l'objet fusionné.
J'ai aussi transmettez tous mes habitants à l'intérieur d'un objet de conteneur I.E. {locals:{g:{prop:val}}}
Donc, dans mon point de vue, je peux faire référence g.prop
qui va simplement revenir null
quand il n'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)
});
C'est une réponse enterrée, mais je l'ai enfin fait fonctionner.
1) Ceci est un exemple autour du module Connect-Flash
2) Ajouter un morceau de middleware dans serveur.js/app.js à ajouter req
à locals
. Cela permet au modèle d'appeler request.flash()
chaque fois qu'il en a besoin. Sans cela, flash()
est consommé sur chaque demande/redirection qui vaincent le but.
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 normal (ceci est CoffeScript, mais rien de spécial)
app.get '/home', (req, res) ->
req.flash "info", "this"
res.render "#{__dirname}/views/index"
4) Appelez demande.Flash () lorsque vous souhaitez les messages. Ils sont consommés sur chaque appel, alors ne la consolez pas. Ils seront partis :-)
!!!
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 aux variables locales dans des modèles rendus dans l'application.
Donc, si vous souhaitez utiliser des locaux dans votre modèle => En supposant que vous disposez d'un moteur NPM du moteur de modèle installé à votre application NODE/Express.
Tout d'abord, vous devez définir les objets locaux express avec vos variables personnalisées dans votre app.js
Fichier, vous pouvez utiliser un objet si plusieurs valeurs sont nécessaires (notre cas dans cet article)
/**
* 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 du fichier de modèle layout.pug
(dans le cas de PUG Modèle de modèle 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"
}