簡體   English   中英

是否可以在快速中間件回調中修改 pug.js 參數 object

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM