NodeJS 是否可以在快速中间件回调中修改pug.js-parameter对象

slwdgvem  于 2023-01-30  发布在  Node.js
关注(0)|答案(1)|浏览(106)

目前,我使用的是一个遗留应用程序,它使用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();
}

显然,我不想用一些逻辑来处理每个实际呈现模板的处理程序,这些逻辑用于检索消息并将它们添加到参数对象中,我想将这个横切关注点移到中间件回调或类似的东西中。
所以,问题是:这可以实现吗?如何实现?我对pug.js还是个新手,也许我忽略了一些显而易见的东西。

2ledvvac

2ledvvac1#

好吧,我找到了一个办法。这就是我所做的:

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使用请求会话来存储消息。它还在某些方面对它们进行过滤。我使用会话是因为应用程序是集群运行的(谢谢,pm2)。由于会话是通过express-mysql-session存储在数据库中的,所以我避免了非粘性会话的问题。

相关问题