![](/img/trans.png)
[英]Is it possible to access and modify a variable passed from Express in Pug?
[英]Is it possible to modify the pug.js-parameter object in an express middleware-callback
目前我正在使用 pug.js 作為 node.js express-app 中的視圖引擎的遺留應用程序。
我想實現一種通用的方式來顯示反饋消息。 我希望能夠顯示消息(成功、錯誤),即使處理程序確實使用重定向進行回復。
這就是我要的:
handlePostRequest(req, res){
// do stuff with the post request
doStuff(req.body);
//This should be done of course somewhere else.
req.session.successes=req.session.successes|[];
//save some success-message for the user
req.session.successes.push("Your post has been saved. Thank you!");
//but reply with a 302
res.redirect(req.headers.referer);
}
//a get request. maybe the handler above redirected here
handleGetRequest(req,res){
// we do NOT get the successes here. Just the 'pure' data.
const renderData=getRenderData();
res.render('fancy-pug-template', renderData);
}
fancyMiddlewareForMessages(req, res, next){
//how to implement getRenderDataByBlackMagic()????
const renderData = getRenderDataByBlackMagic();
//set the messages
renderData.successes = req.session.successes;
//empty saved messages
req.session.successes = [];
next();
}
顯然,我不想污染每個實際呈現模板的處理程序,這些處理程序具有一些邏輯,這些邏輯檢索消息並將它們添加到參數 object。我想在中間件回調或類似的東西中移動這個橫切關注點。
所以,問題是:這能實現嗎? 如何? 我是 pug.js 的新手,也許我忽略了一些明顯的東西。
好的,我找到了一個方法。 這就是我所做的:
const requestStorage = new AsyncLocalStorage<Request>();
function patchRenderFunction(req: Request, res: Response, next: NextFunction) {
const render = res.render;
res.render = function (view: string, options?: any, callback?: (err: Error, html: string) => void) {
const messages = new MessageManager(req);
//merge errorMessages
options.errorMessages = mergeMessageArrays(options.errorMessages, messages.errors);
//same for successMessages
options.successMessages = mergeMessageArrays(options.successMessages, messages.successes);
render.bind(this)(view, options, callback);
};
requestStorage.run(req, () => {
next();
});
}
export function applyAutomaticRenderAttributes(app: Express): void {
app.use(patchRenderFunction);
}
export function successMessage(message: string, req?: Request) {
if (!req) {
req = requestStorage.getStore();
}
if (!req) {
console.error('No request found in async storage. This should not happen. Please report this issue. (successMessage)');
return;
}
new MessageManager(req).addSuccessMessage(message);
}
//export function errorMessage(...) omitted
MessageManager 使用請求 session 來存儲消息。 它還在某些方面過濾它們。 我正在使用 session,因為該應用程序運行集群(謝謝 pm2)。 由於 session 通過express-mysql-session
存儲在數據庫中,我避免了非粘性會話的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.