it-swarm.com.de

Wie erstelle ich globale Variablen, auf die in allen Ansichten mit Express / Node.JS zugegriffen werden kann?

Ok, ich habe ein Blog mit Jekyll erstellt und Sie können Variablen in einer Datei _config.yml Definieren, auf die in allen Vorlagen/Layouts zugegriffen werden kann. Ich verwende derzeit Node.JS / Express mit EJS templates und ejs- Einheimische (für Partials/Layouts. Ich versuche, etwas Ähnliches wie die globalen Variablen site.title in _config.yml zu tun, wenn jemand mit Jekyll vertraut ist. Ich habe Variablen wie die Site-Titel (anstelle des Seitentitels), Autor/Firmenname, der auf allen meinen Seiten gleich bleibt.

Hier ist ein Beispiel für das, was ich gerade mache:

exports.index = function(req, res){
    res.render('index', { 
        siteTitle: 'My Website Title',
        pageTitle: 'The Root Splash Page',
        author: 'Cory Gross',
        description: 'My app description',
        indexSpecificData: someData
    });
};

exports.home = function (req, res) {
    res.render('home', {
        siteTitle: 'My Website Title',
        pageTitle: 'The Home Page',
        author: 'Cory Gross',
        description: 'My app description',
        homeSpecificData: someOtherData
    });
};

Ich möchte in der Lage sein, Variablen wie den Titel, die Beschreibung, den Autor usw. meiner Site an einer Stelle zu definieren und sie in meinen Layouts/Vorlagen über EJS zugänglich zu machen, ohne sie bei jedem Aufruf von res.render Als Optionen übergeben zu müssen. . Gibt es eine Möglichkeit, dies zu tun und es mir trotzdem zu ermöglichen, andere Variablen für jede Seite einzugeben?

73
Cory Gross

Nachdem ich die Gelegenheit hatte, die Express 3 API-Referenz etwas genauer zu studieren, entdeckte ich, wonach ich suchte zum. Speziell die Einträge für app.locals und dann etwas weiter unten res.locals enthielt die Antworten, die ich brauchte.

Ich habe selbst herausgefunden, dass die Funktion app.locals Ein Objekt annimmt und alle seine Eigenschaften als globale Variablen speichert, die für die Anwendung gültig sind. Diese globalen Variablen werden als lokale Variablen an jede Ansicht übergeben. Die Funktion res.locals Ist jedoch auf die Anforderung beschränkt und daher sind lokale Antwortvariablen nur für die Ansichten zugänglich, die während dieser bestimmten Anforderung/Antwort gerendert wurden.

Für meinen Fall in meinem app.js Habe ich Folgendes hinzugefügt:

app.locals({
    site: {
        title: 'ExpressBootstrapEJS',
        description: 'A boilerplate for a simple web application with a Node.JS and Express backend, with an EJS template with using Twitter Bootstrap.'
    },
    author: {
        name: 'Cory Gross',
        contact: '[email protected]'
    }
});

Dann sind alle diese Variablen in meinen Ansichten als site.title, site.description, author.name, author.contact Zugänglich.

Ich könnte auch lokale Variablen für jede Antwort auf eine Anfrage mit res.locals Definieren oder einfach Variablen wie den Seitentitel als optionsParameter im render -Aufruf übergeben.

EDIT: Mit dieser Methode können Sie nicht diese Locals in Ihrer Middleware verwenden. Ich bin tatsächlich darauf gestoßen, wie Pickels im Kommentar unten vorschlägt. In diesem Fall müssen Sie eine Middleware-Funktion als solche in seiner alternativen (und geschätzten) Antwort erstellen. Ihre Middleware-Funktion muss sie für jede Antwort zu res.locals Hinzufügen und dann next aufrufen. Diese Middleware-Funktion muss über jeder anderen Middleware platziert werden, die diese Gebietsschemas verwenden muss.

EDIT: Ein weiterer Unterschied zwischen der Deklaration von Einheimischen über app.locals Und res.locals Besteht darin, dass die Variablen mit app.locals Angegeben werden werden einmalig festgelegt und bleiben während der gesamten Laufzeit der Anwendung bestehen. Wenn Sie in Ihrer Middleware Locals mit res.locals Festlegen, werden diese jedes Mal festgelegt, wenn Sie eine Anfrage erhalten. Grundsätzlich sollten Sie es vorziehen, globale Werte über app.locals Festzulegen, es sei denn, der Wert hängt von der Variable request req ab, die an die Middleware übergeben wird. Wenn sich der Wert nicht ändert, ist es effizienter, ihn nur einmal in app.locals Einzustellen.

100
Cory Gross

Sie können dies tun, indem Sie sie in einer allgemeinen Middleware zum lokalen Objekt hinzufügen.

app.use(function (req, res, next) {
   res.locals = {
     siteTitle: "My Website's Title",
     pageTitle: "The Home Page",
     author: "Cory Gross",
     description: "My app's description",
   };
   next();
});

Locals ist auch eine Funktion, die das lokale Objekt erweitert, anstatt es zu überschreiben. Das Folgende funktioniert also auch

res.locals({
  siteTitle: "My Website's Title",
  pageTitle: "The Home Page",
  author: "Cory Gross",
  description: "My app's description",
});

Vollständiges Beispiel

var app = express();

var middleware = {

    render: function (view) {
        return function (req, res, next) {
            res.render(view);
        }
    },

    globalLocals: function (req, res, next) {
        res.locals({ 
            siteTitle: "My Website's Title",
            pageTitle: "The Root Splash Page",
            author: "Cory Gross",
            description: "My app's description",
        });
        next();
    },

    index: function (req, res, next) {
        res.locals({
            indexSpecificData: someData
        });
        next();
    }

};


app.use(middleware.globalLocals);
app.get('/', middleware.index, middleware.render('home'));
app.get('/products', middleware.products, middleware.render('products'));

Ich habe auch eine generische Render-Middleware hinzugefügt. Auf diese Weise müssen Sie nicht zu jeder Route res.render hinzufügen, was bedeutet, dass Sie den Code besser wiederverwenden können. Sobald Sie die Route der wiederverwendbaren Middleware eingeschlagen haben, werden Sie feststellen, dass Sie viele Bausteine ​​haben, die die Entwicklung enorm beschleunigen.

49
Pickels

Bei Express 4.0 stellte ich fest, dass die Verwendung von Variablen auf Anwendungsebene etwas anders funktioniert und Corys Antwort bei mir nicht funktioniert hat.

Aus den Dokumenten: http://expressjs.com/en/api.html#app.locals

Ich habe festgestellt, dass Sie eine globale Variable für die App in deklarieren können

app.locals

z.B

app.locals.baseUrl = "http://www.google.com"

Und dann können Sie in Ihrer Anwendung auf diese Variablen zugreifen und in Ihrer Express-Middleware können Sie im req-Objekt als auf sie zugreifen

req.app.locals.baseUrl

z.B.

console.log(req.app.locals.baseUrl)
//prints out http://www.google.com
16
RamRovi

In Ihrer app.js müssen Sie so etwas hinzufügen

global.myvar = 100;

Jetzt können Sie in all Ihren Dateien, in denen Sie diese Variable verwenden möchten, einfach als myvar darauf zugreifen.

11
Fernando Bustos

sie können auch "global" verwenden

Beispiel:

deklarieren wie folgt:

  app.use(function(req,res,next){
      global.site_url = req.headers.Host;   // hostname = 'localhost:8080'
      next();
   });

Verwendung wie folgt: In allen Ansichten oder EJS-Dateien <% console.log (site_url); %>

in js files console.log (site_url);

1
Shaik Matheen

Eine Möglichkeit, dies durch Aktualisieren des app.locals Variable für diese App in app.js

Stellen Sie über folgendes ein

var app = express();
app.locals.appName = "DRC on FHIR";

Zugang erhalten

app.listen(3000, function () {
    console.log('[' + app.locals.appName + '] => app listening on port 3001!');
});

Ausarbeitung mit einem Screenshot aus @RamRovi-Beispiel mit geringfügiger Verbesserung.

enter image description here

1
Gajen Sunthara

Um einen verschmutzten globalen Bereich zu vermeiden, erstelle ich ein Skript, das ich überall einfügen kann.

// my-script.js
const ActionsOverTime = require('@bigteam/node-aot').ActionsOverTime;
const config = require('../../config/config').actionsOverTime;
let aotInstance;

(function () {
  if (!aotInstance) {
    console.log('Create new aot instance');
    aotInstance = ActionsOverTime.createActionOverTimeEmitter(config);
  }
})();

exports = aotInstance;

Auf diese Weise wird nur einmal eine neue Instanz erstellt und diese überall dort freigegeben, wo die Datei enthalten ist. Ich bin nicht sicher, ob es daran liegt, dass die Variable zwischengespeichert ist oder an einem internen Referenzmechanismus für die Anwendung (der möglicherweise das Zwischenspeichern umfasst). Alle Kommentare dazu, wie der Knoten dies löst, wären großartig.

Vielleicht lesen Sie auch diese Informationen, um zu erfahren, wie die erforderlichen Funktionen funktionieren: http://fredkschott.com/post/2014/06/require-and-the-module-system/

0
dewwwald