2016-10-10 5 views
0

ほとんどのページが1つのレイアウトでレンダリングされるWebアプリケーションのためのかなり標準的な要件があります(ハンドルバーを使用していますが、同じことがJadeまたは何か他のもの)。express.jsページレイアウトにデータを設定する方法

レイアウトでは、データベースのかなりのデータが使用され、いくつかのルックアップが必要な場合があります。レイアウトで使用されるデータをページ/ルートごとに各コントローラで取得する必要がないように、コードをどのように構造化する必要がありますか?多くのWebフレームワークでは、パターンを経由して経路を傍受し、その傍受者が必要なルックアップを作成し、ラップするコントローラによって生成されたモデルを装飾する簡単な方法があります。

ミドルウェアの正しい定義でそれを行うには何らかの方法があるように感じますが、わかりません。

router.get('/', ctrlPublic.index); 
router.get('/index.html', ctrlPublic.index); 
router.get('/find-us.html', ctrlPublic.findUs); 

// apply same interceptor to all (/*) 
router.intercept('/*', ctrlDecorator.main); 

// ctrlPublic... 
index: function(req, res) { 
    // get data for index page, then render index.hbs 
}, 
findUs: function(req, res) { 
    // get data for find-us page, then render find-us.hbs 
} 

// ctrlDecorator... 
main: function(req, res) { 
    // lookup data needed by main layout - this gets automatically 
    // added to the model used by the page ctrlPublic handlers 
} 

を私は理想的なインターセプタのようなパターンマッチングではなく、router.get()呼び出しで宣言によってコントローラーを標的とする、と彼らはそう添加剤であるためには:以下の私の擬似コードを示して何ん何かお探し

特定のコントローラーのセットに複数のものを適用することができます。

これを手助けするモジュールがありますか、それを達成するための一般的な「ベストプラクティス」の方法はありますか?

答えて

1

あなたの質問を正しく理解するには、グローバルミドルウェアがデータを取得して対応するコントローラに渡す必要がありますので、コントローラで同じレイアウトデータを読み込まないようにしてください。その場合

あなたがreq.layoutDataを使用する場合は、グローバルミドルウェア

app.use(function(req, res, next){ 
    var excludeMiddleware = ['login', 'test', 'test2']; 
    //simple example for bypassing the middleware 
    for(var i = 0; i < excludeMiddleware.length; i++){ 
     if(excludeMiddleware[i] === req.path) { return next(); } 
    }     

    someAsyncFnFromDb.then(function(dataFromDb){ 
     //req.layoutData = dataFromDb;   
     res.locals.layoutData = dataFromDb; 
     return next(); 
    }).catch(function(err){ 
     return next(); // or throw new Error(err) 
    }); 
}); 

とあなたのコントローラーでの作成、レンダリング機能にデータを割り当て、例

res.render('myView', { layoutData: req.layoutData }); 

たり場合であるとして、あなたのコントローラを残しますres.locals.layoutDataを使用すると、layoutDataが表示されます。

+0

はい、あなたはデータの使用について理解しており、そのようなソリューションはレイアウトデータをキャッシュするのにも適しています。しかし、ミドルウェアの使用方法を変更するには、潜在的に多くのコントローラとルートの宣言を変更する必要があります。このようなミドルウェアは、すべてのコントローラで繰り返すのではなく、コンベンションやパターンマッチングなどで適用できますか? – darrend

+0

ルートを定義する前にミドルウェアを定義すると、すべてのルートに自動的に挿入され、 'req.layoutData = dataFromDb;'を 'res.locals.layoutData = dataFromDb;に変更すると、何も変更する必要はありませんあなたのコントローラlayoutDataはすべてのテンプレートで利用可能になります。パターンマッチングのために、layoutDataをロードする必要がない場合、いくつかのルートを除外することができます。 –

+0

ok、はい、それは良いですが、それらを除外するためにコントローラについて知っているインターセプタ(ミドルウェア)はちょっと逆です。私は少し驚いていました。他のすべての言語で使用していたすべてのWebフレームワークには、このような性質があるため、私は一部のファーストクラスの機能を欠いていると思いました。私は、sailsjs.orgが、この上位レベルの機能を明示的なアプリケーションに提供していると思っています。 – darrend

関連する問題