46 votes

Vue "globaux" d'Express.js

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 "locals". ( res.render("template", { locals: { foo: "bar" } }); )

Existe-t-il un moyen d'avoir des "globaux" ? (c'est-à-dire des données qui sont accessibles à toutes les vues).

J'ai vu view options mais ce n'est pas récursif, donc il remplace les locales que j'ai définies si j'utilise des locales avec mon modèle.

Voici mon cas d'utilisation : Je veux faire en sorte que les fichiers CSS/JS puissent être ajoutés sur une base par page, et cela fait partie de ma mise en page principale. Le problème, c'est que si je ne configure pas explicitement ces tableaux à chaque rendu, j'obtiens une erreur non définie. typeof css !== "undefined" danse. En outre, j'ai d'autres listes d'options de boîtes de sélection que je ne veux pas avoir à ajouter explicitement à chacun de mes formulaires.

58voto

tigerFinch Points 736

Il convient de noter, pour ceux qui auraient rencontré cette question depuis la sortie d'Express 3, que la méthode "dynamicHelpers" n'existe plus.

Au lieu de cela, vous pouvez utiliser la fonction app.locals, qui agit comme un objet dans lequel vous pouvez stocker des valeurs ou des fonctions, et qui les met ensuite à la disposition 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 requête pour en tirer des informations, vous pouvez écrire une simple fonction middle-ware et utiliser la variable app.settings.

Par exemple, si vous utilisez connect-flash pour fournir des messages à vos utilisateurs, vous pourriez 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 =settings.error dans votre modèle.

Ces sujets sont abordés ici, bien que de manière un peu succincte : http://expressjs.com/api.html#app.locals

10voto

alessioalex Points 27001

Il existe un moyen d'avoir des variables "globales" pour les vues, en utilisant des aides de vue dynamiques.

Du guide Express.js :

app.dynamicHelpers(obj)

Enregistre les aides de vue dynamiques. Les aides de vue dynamiques sont simplement qui acceptent req, res, et sont évaluées par rapport à l'instance Server avant qu'une vue ne soit rendue. La valeur de retour de cette fonction devient la variable locale à laquelle elle est associée.

app.dynamicHelpers({session : function(req, res){ return req.session ; } }) ;

Toutes les vues auront désormais la session disponible afin que les données de session puissent être accessibles via session.name etc :

<%= session.name %>

Vous trouverez ici un exemple concret de leur utilisation : https://github.com/alessioalex/Nodetuts/tree/master/express_samples (node app.js pour démarrer l'application)

8voto

mikl Points 5906

Un exemple concret de l'utilisation des options de vue comme le mentionne l'auteur :

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 ensuite dans mon layout.jade (modèle de base pour l'application dans mon cas) :

link(rel='stylesheet', href='http://stackoverflow.com/static/css/' + assetVersion + '/style.css')
script(src='/static/js/' + assetVersion + '/script.js')

Grâce à cette petite astuce, il me suffit de mettre à jour le fichier assetVersion un endroit variable pour s'assurer que mes actifs ne sont pas mis en cache dans Varnish ou d'autres endroits.

4voto

Dominic Barnes Points 13815

J'ai fini par regarder dans le code source, et j'ai découvert que cela est maintenant possible dans les versions précédentes d'Express. (jusqu'à présent, uniquement disponible via GitHub)

1voto

Daniel Beardsley Points 6802

La façon la plus simple d'y parvenir est de créer une variable qui représente l'ensemble par défaut de locaux pour vos vues. Ensuite, créez une fonction qui accepte un objet, le fusionne avec les locales, et renvoie l'objet fusionné.

J'ai aussi passer TOUS mes locaux dans un objet conteneur c'est-à-dire {locals:{g:{prop:val}}} donc dans mes vues je peux faire référence g.prop qui retournera simplement 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)
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X