Express.js View “globali”
-
12-10-2019 - |
Domanda
Sto usando Express.js (su Node.js) e so che si può rendere una vista con dati personalizzati tramite il parametro "locali". (res.render("template", { locals: { foo: "bar" } });
)
C'è un modo per avere "globali"? (Es. I dati che è accessibile ad ogni vista)
Ho visto view options
, ma che non è ricorsiva, in modo che sostituisce la gente del posto dispositivo se si utilizzano qualsiasi locali con il mio modello.
Questo è il mio caso d'uso: voglio fare in modo che i CSS / JS file può essere aggiunto su una base per-page, e che fa parte del mio layout principale. Il problema è che, se non impostata in modo esplicito quelle matrici su ogni render, ottengo un errore non definito, quindi nel mio modello devo sempre fare la danza typeof css !== "undefined"
. Inoltre, ho altri elenchi Selezionare l'opzione di dialogo che non voglio avere per aggiungere in modo esplicito a ciascuna delle mie forme.
Soluzione
E 'degno di nota per coloro che possono avere incontrato questa domanda dopo il rilascio di Express 3, che i 'dynamicHelpers' metodo non esiste più.
Invece è possibile utilizzare la funzione di app.locals, che agisce come un oggetto è possibile memorizzare valori o funzioni, e poi li rende disponibili a vista. Ad esempio: -
// 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
Se è necessario l'accesso all'oggetto richiesta di informazioni di pull da, è possibile scrivere una semplice funzione di middleware e di utilizzare la variabile app.settings.
Ad esempio, se si sta utilizzando Connect-flash per fornire messaggi agli utenti, si potrebbe fare qualcosa di simile:
app.use(function(req, res, next) {
app.set('error', req.flash('error'));
next();
});
che darebbe accesso al messaggio di errore con = settings.error nel modello.
Questi argomenti sono trattati qui, seppur di poco brevemente: http://expressjs.com/api. html # app.locals
Aggiornamento: Express 4
app.locals
è ora un semplice oggetto JavaScript, in modo che ogni proprietà deve essere impostato uno per uno.
app.locals.version = 3;
app.locals.somefunction = function() {
return "function result";
}
res.locals
fornisce la stessa identica funzionalità, tranne che deve essere utilizzato per i dati di richiesta-specifici, piuttosto che i dati a livello di applicazione. Un oggetto utente o le impostazioni è un caso d'uso comune.
res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
backgroundColor: 'fff'
}
Altri suggerimenti
C'è un modo per avere le variabili "globali" per le viste, utilizzando la vista aiutanti dinamici.
Dalla guida Express.js:
app.dynamicHelpers (obj)
Registri visione dinamica aiutanti. Vista dinamica aiutanti sono semplicemente funzioni che accettano req, res, e vengono valutate contro il Server esempio prima vista viene reso. Il valore restituito da questa funzione diventa la variabile locale è associato a.
app.dynamicHelpers ({sessione: funzione (req, res) { tornare req.session; }});
Tutte le viste ora avrebbe sessione disponibili in modo che i dati della sessione possono essere accedere tramite i session.name etc:
È possibile trovare un vero e proprio esempio di come usarli qui: https: // GitHub .com / alessioalex / Nodetuts / albero / master / express_samples (nodo app.js per avviare l'applicazione)
Un esempio reale di utilizzo di opzioni di visualizzazione come l'autore citato:
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
});
E poi nel mio layout.jade (modello di base per l'applicazione nel mio caso):
link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')
Con questo piccolo trucco, ho solo aggiornare la variabile assetVersion
un posto per assicurarsi che i miei beni non vengono memorizzate nella cache in vernice o in altri luoghi.
I liquidata esaminando il codice sorgente, e ho effettivamente trovato che questo è ora possibile nei non versioni di Express. (Finora, disponibile solo tramite GitHub)
Il modo più semplice per raggiungere questo obiettivo è quello di creare una variabile che rappresenta l'insieme predefinito di locali per le vostre opinioni. Quindi creare una funzione che accetta un oggetto, si fonde con la gente del posto, e restituisce l'oggetto risultante dalla fusione.
Ho anche passare tutti i miei locali all'interno di un oggetto contenitore cioè {locals:{g:{prop:val}}}
così nel mio punto di vista posso refernce g.prop
che sarà solo tornare null
quando non è impostato, invece di lanciare un errore indefinito.
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)
});
Questa è una risposta sepolta, ma alla fine ho capito di lavoro.
1) Questo è un esempio intorno al modulo connect-flash
2) Aggiungere un pezzo di middleware in server.js / app.js aggiungere req
a locals
. In questo modo il modello di chiamata request.flash()
ogni volta che ha bisogno. Senza questo, flash()
si consuma su ogni richiesta / reindirizzamento sconfiggendo lo scopo.
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) Imposta il percorso come normale (questo è CoffeeScript, ma niente di speciale)
app.get '/home', (req, res) ->
req.flash "info", "this"
res.render "#{__dirname}/views/index"
4) chiamata request.flash () quando si desidera che i messaggi. Sono consumati per ogni chiamata, quindi non li console.log o se ne andranno: -)
!!!
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
È possibile accedere a variabili locali nei modelli resi all'interno dell'applicazione.
Quindi, se si desidera utilizzare i locali nel modello => a patto di avere un motore di template NPM installato il nodo / esprimere applicazione.
In primo luogo, è necessario impostare il esprimono locali oggetti con la vostra abitudine variabili nel file di app.js
, è possibile utilizzare un oggetto se sono necessari più valori (il nostro caso in questo 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'
}
};
Quindi, per accedere ai valori nel file modello layout.pug
(nel caso del motore di template PUG per esempio)
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}
Testato con
"dependencies": {
"express": "^4.16.3",
"pug": "^2.0.3"
}