web-dev-qa-db-fra.com

Express.js Voir "Globals"

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.

44
Dominic Barnes

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

Mise à jour: Express 4

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'
}
57
tigerFinch

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)

10
alessioalex

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.

7
mikl

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)

4
Dominic Barnes

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)
});
1
Daniel Beardsley

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
0
Michael Cole

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"
  }
0
Drozerah