2016-10-10 35 views
0

我對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

如果我理解您的問題,您需要一個全局中間件來獲取數據並將其傳遞給相應的控制器,以便您不會在控制器上加載相同的佈局數據?

在這種情況下,建立一個全球性的中間件

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

,並在控制器的數據分配給渲染功能,如果您使用req.layoutData,例如

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

或者留下您的控制器是,如果你使用res.locals.layoutData,layoutData將在您的視圖中可用。

+0

是的,您對數據使用的理解是正確的,像這樣的解決方案也可以緩存我也需要的佈局數據。但是,如何改變中間件的使用涉及到更改潛在的許多控制器和路由的聲明,這似乎很不雅觀。例如,這種中間件可以按照約定或模式匹配來應用,而不是在每個控制器中重複它? – darrend

+0

如果您在定義任何路由之前定義了該中間件,那麼它將自動注入到每個路由中,並且如果將'req.layoutData = dataFromDb;'更改爲'res.locals.layoutData = dataFromDb;',那麼您不需要更改任何內容你的控制器layoutData將在每個模板上都可用。現在對於模式匹配,如果你不需要加載layoutData,你可以排除一些路由。我舉了一個例子來看更新的答案。 –

+0

好的,是的,它更好,但攔截器(中間件)知道控制器以便排除它們有點落後。我起初有點驚訝,我以爲我錯過了一些express的一流功能,因爲我用在其他語言中的每個web框架都具有這種性質。我想sailsjs.org是爲快速應用程序提供這種更高級別的功能的集合..似乎更多的是我從掃視後看到的。 – darrend

相關問題