Express.js View „Globals“
-
12-10-2019 - |
Frage
Ich bin mit Express.js (auf Node.js) und ich weiß, dass Sie eine Ansicht mit benutzerdefinierten Daten über den „Einheimischen“ Parameter machen kann. (res.render("template", { locals: { foo: "bar" } });
)
Gibt es eine Möglichkeit „Globals“ zu haben? (Dh. Daten, die für jede Ansicht zugänglich ist)
Ich sah view options
, aber das ist nicht rekursiv, so dass es die Einheimischen ersetzt ich gesetzt, wenn ich irgendwelche Einheimischen mit meiner Vorlage verwenden.
Das ist mein Anwendungsfall: Ich will es machen, so dass CSS / JS-Dateien können auf einer Pro-Seite-Basis hinzugefügt werden, und das ist ein Teil meines Haupt Layout. Das Problem ist, wenn ich nicht explizit diese Arrays auf jedem machen gesetzt, ich einen undefinierten Fehler erhalten, so in meiner Vorlage Ich habe immer den typeof css !== "undefined"
Tanz zu tun. Darüber hinaus habe ich andere Auswahlbox Optionslisten, dass ich nicht zu jedem meiner Formulare müssen explizit hinzufügen wollen.
Lösung
Es lohnt sich für diejenigen, die unter Hinweis darauf, seit der Veröffentlichung von Express 3 über diese Frage gekommen sein, dass die Methode ‚dynamicHelpers‘ existiert nicht mehr.
Sie können stattdessen die app.locals Funktion verwenden, die als Objekt fungiert Sie in Werten oder Funktionen speichern, und dann macht sie zu Ansichten zur Verfügung. Zum Beispiel: -
// 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
Wenn Sie Zugriff auf das Request-Objekt zu ziehen Informationen benötigen aus, können Sie eine einfache Middleware-Funktion schreiben und die AnwendgsOptionen Variable verwenden.
Zum Beispiel, wenn Sie connect-Flash verwenden, um Nachrichten an die Benutzer zur Verfügung zu stellen, könnte man so etwas tun:
app.use(function(req, res, next) {
app.set('error', req.flash('error'));
next();
});
Welche würden Sie auf die Fehlermeldung Zugriff mit = settings.error in Ihrer Vorlage.
Diese hier behandelten Themen, wenn auch etwas kurz: http://expressjs.com/api. html # app.locals
Update: Express 4
app.locals
ist jetzt ein einfaches JavaScript-Objekt, so dass jedes Objekt einzeln sein.
app.locals.version = 3;
app.locals.somefunction = function() {
return "function result";
}
res.locals
bietet genau die gleiche Funktionalität, außer es für anforderungsspezifischen Daten verwendet werden soll, anstatt anwendungsweiten Daten. Ein Benutzerobjekt oder Einstellungen ist ein häufiger Anwendungsfall.
res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
backgroundColor: 'fff'
}
Andere Tipps
Es gibt einen Weg „globale“ Variablen für Ansichten zu haben, dynamische Ansicht Helfer verwendet wird.
Von der Express.js Führung:
app.dynamicHelpers (obj)
Register dynamische Ansicht Helfer. Dynamische Ansicht Helfer sind einfach Funktionen, die req, res akzeptieren, und gegen den Server ausgewertet Instanz vor dem Ziel gemacht wird. Der Rückgabewert dieser Funktion wird die lokale Variable ist im Zusammenhang mit.
app.dynamicHelpers ({Sitzung: Funktion (REQ, res) { Rückkehr req.session; }});
Alle Ansichten würden jetzt Sitzung haben zur Verfügung, so dass Sitzungsdaten sein können, Zugriff über session.name etc:
Sie können ein echtes Beispiel finden, wie sie hier verwenden: https: // Github .com / alessioalex / Nodetuts / Baum / Master / express_samples (Knoten app.js die Anwendung zu starten)
Ein reales Beispiel der Verwendung von Ansichtsoptionen wie der Autor erwähnt:
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
});
Und dann in meiner layout.jade (Basisvorlage für die App in meinem Fall):
link(rel='stylesheet', href='/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')
Mit diesem kleinen Trick, ich muß nur das assetVersion
Variable einen Ort aktualisieren, um sicherzustellen, dass mein Vermögen ist in Lack oder an anderen Orten nicht im Cache gespeichert.
Ich ziehe einen Blick in den Quellcode, und ich habe festgestellt, dass dies tatsächlich möglich ist nie Versionen von Express. (Bisher nur über GitHub)
Der einfachste Weg, dies zu tun ist, eine Variable zu erstellen, die den Standardsatz von Einheimischen für Ihre Ansichten darstellt. Dann eine Funktion erstellen, die ein Objekt übernimmt, verschmilzt sie mit den Einheimischen, und kehrt das fusionierte Objekt.
ich auch passieren alle meine Einheimischen in einem Container-Objekt dh {locals:{g:{prop:val}}}
so in meine Ansichten kann ich g.prop
refernce die gerade null
zurückkehren wird, wenn es nicht gesetzt ist, anstatt einen undefinierten Fehler werfen.
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)
});
Dies ist eine vergrabene Antwort, aber ich habe es endlich an der Arbeit.
1) Dies ist ein Beispiel um das Modul connect-flash
2) ein Stück Middleware in server.js Hinzufügen / app.js req
zu locals
hinzuzufügen. Auf diese Weise können die Vorlage Anruf request.flash()
, wann immer sie benötigt. Ohne diese flash()
wird bei jeder Anfrage / Redirect verbraucht den Zweck zu besiegen.
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) Richten Sie Ihre Route als normal (das ist Coffeescript, aber nichts Besonderes)
app.get '/home', (req, res) ->
req.flash "info", "this"
res.render "#{__dirname}/views/index"
4) Anruf request.flash (), wenn Sie die Nachrichten. Sie werden bei jedem Aufruf verbraucht, so dass nicht sie tun console.log oder sie werden gegangen: -)
!!!
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
Sie können innerhalb der Anwendung gerendert lokale Variablen in Vorlagen zugreifen zu können.
Also, wenn Sie irgendwelche Einheimischen in der Vorlage verwenden möchten => vorausgesetzt, Sie eine Template-Engine npm zu Ihrem Knoten installiert haben / express Anwendung.
Zuerst müssen Sie die Einheimischen ausdrücken Objekte mit Ihrer benutzerdefinierten Variablen in Ihrer app.js
Datei, können Sie ein Objekt, wenn mehrere Werte verwenden (unser Fall in diesem Beitrag) erforderlich sind,
/**
* 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'
}
};
Dann der Zugriff auf die Werte in der Template-Datei layout.pug
(im Fall von PUG Template-Engine zum Beispiel)
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}
Getestet mit
"dependencies": {
"express": "^4.16.3",
"pug": "^2.0.3"
}