45

私は Express.js (Node.js 上) を使用していますが、「locals」パラメーターを介してカスタム データを使用してビューをレンダリングできることを知っています。( res.render("template", { locals: { foo: "bar" } });)

「グローバル」を持つ方法はありますか?(つまり、すべてのビューからアクセスできるデータ)

を見ましたview optionsが、それは再帰的ではないため、テンプレートでローカルを使用すると、設定したローカルが置き換えられます。

これが私の使用例です。CSS/JS ファイルをページごとに追加できるようにしたいと考えています。これは私のメイン レイアウトの一部です。問題は、すべてのレンダリングでこれらの配列を明示的に設定しないと、未定義のエラーが発生するため、テンプレートで常にtypeof css !== "undefined"ダンスを行う必要があることです。さらに、各フォームに明示的に追加したくない他の選択ボックス オプション リストがあります。

4

7 に答える 7

57

Express 3のリリース以降、この質問に出くわした可能性のある人にとっては、メソッド「dynamicHelpers」が存在しなくなったことは注目に値します。

代わりに、app.locals関数を使用できます。この関数は、値または関数を格納できるオブジェクトとして機能し、それらをビューで使用できるようにします。例えば:-

// 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

情報を取得するためにリクエストオブジェクトにアクセスする必要がある場合は、単純なミドルウェア関数を記述して、app.settings変数を使用できます。

たとえば、connect-flashを使用してユーザーにメッセージを提供している場合は、次のようにします。

app.use(function(req, res, next) {
    app.set('error', req.flash('error'));
    next();
});

これにより、テンプレートに=settings.errorが含まれるエラーメッセージにアクセスできるようになります。

これらのトピックについては、少し簡単に説明しますが、ここで説明します:http: //expressjs.com/api.html#app.locals

更新:Express 4

app.localsは単純なJavaScriptオブジェクトになっているため、すべてのプロパティを1つずつ設定する必要があります。

app.locals.version = 3;
app.locals.somefunction = function() {
    return "function result";
}

res.localsアプリケーション全体のデータではなく、リクエスト固有のデータに使用する必要があることを除いて、まったく同じ機能を提供します。ユーザーオブジェクトまたは設定は、一般的なユースケースです。

res.locals.user = req.isAuthenticated() ? req.user : null;
res.locals.userSettings = {
    backgroundColor: 'fff'
}
于 2012-10-13T17:18:42.670 に答える
10

動的ビュー ヘルパーを使用して、ビューに「グローバル」変数を設定する方法があります。

Express.js ガイドから:

app.dynamicHelpers(obj)

動的ビュー ヘルパーを登録します。動的ビュー ヘルパーは、req、res を受け入れる単純な関数であり、ビューがレンダリングされる前に Server インスタンスに対して評価されます。この関数の戻り値は、関連付けられているローカル変数になります。

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

session.name などを介してセッション データにアクセスできるように、すべてのビューでセッションが利用可能になります。

ここでそれらの使用方法の実際の例を見つけることができます: https://github.com/alessioalex/Nodetuts/tree/master/express_samples (アプリを起動するノード app.js)

于 2011-06-16T10:41:18.870 に答える
8

著者が述べたように、ビューオプションを使用する実際の例:

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
  });

そして、私のlayout.jade(私の場合はアプリのベーステンプレート):

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

このちょっとしたトリックで、assetVersion変数を1か所更新するだけで、アセットがVarnishやその他の場所にキャッシュされないようになります。

于 2011-12-24T21:04:12.033 に答える
4

ソースコードを調べてみたところ、これが Express の決してバージョンで可能になったことがわかりました。(これまでのところ、GitHub からのみ利用可能)

于 2011-01-19T21:17:00.380 に答える
1

これを実現する最も簡単な方法は、ビューのローカルのデフォルトセットを表す変数を作成することです。次に、オブジェクトを受け入れ、それをローカルとマージして、マージされたオブジェクトを返す関数を作成します。

また、すべてのローカルをコンテナオブジェクト内に渡します。つまり{locals:{g:{prop:val}}} 、ビューでは、未定義のエラーをスローする代わりに、設定されていないときにg.prop返される参照を参照できます。null

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)
});
于 2011-01-18T22:48:20.290 に答える
0

これは埋もれた応答ですが、ようやく機能するようになりました。

1) これは、モジュールconnect-flashに関する例です。

2) server.js/app.js にミドルウェアを追加して に追加reqlocalsます。これにより、テンプレートはrequest.flash()必要なときにいつでも呼び出すことができます。これがないと、flash()各リクエスト/リダイレクトで消費され、目的に反します。

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) 通常どおりルートを設定します (これは coffeescript ですが、特別なことは何もありません)。

app.get '/home', (req, res) ->
  req.flash "info", "this"
  res.render "#{__dirname}/views/index"

4) メッセージが必要な場合は request.flash() を呼び出します。それらは呼び出しごとに消費されるため、それらを console.log しないでください。そうしないと、消えてしまいます :-)

!!!
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
于 2013-06-19T03:03:19.383 に答える