简体   繁体   English

Express JS Dynamic app.local / res.local变量

[英]Express JS Dynamic app.local/res.local Variables

I'm trying to load some variables into the view render site wide to build dynamic menus. 我正在尝试将一些变量加载到整个视图渲染站点中,以构建动态菜单。 I've got a neo4j database on the back end that keeps all the menu structures and I'm accessing it via APOC (ignore the hackish Cypher queries I'm structuring data in cypher I probably should be doing in . 我在后端有一个neo4j数据库,该数据库保留了所有菜单结构,并且正在通过APOC访问它(忽略我正在使用应该在cypher中构造数据的hacky Cypher查询。

My first solution was just to assign the a function to app.locals and call it in the view a la: 我的第一个解决方案是将一个函数分配给app.locals并在视图la中将其调用:

//app.js
app.locals.catMenuQuery = function(){
  var query = apoc.query(
    'MATCH (c:Category)-[o:CHILD_OF]->(m:Menu {url: "cat-menu"}) \
      OPTIONAL MATCH (c2:Category)-[o2:CHILD_OF]->(c) \
      WITH c, c2, o, o2 \
      ORDER BY o2.order, c2.name \
      WITH \
        { \
          name: c.name, \
          url: c.url, \
          children: collect(c2),\
          order: o.order \
        } AS rows \
      ORDER BY rows.order \
      RETURN collect(rows)'
  );
  query.exec().then(function (qres) {
    var data = qres[0]['data'][0]['row'][0];
    return data;
  }, function (fail) {
    console.log(fail)
  });
}

//view.pug
ul#cat-menu.in
  each cat in catMenuQuery()
    li(class= cat.url)
      h1= cat.name
      ul
        each child in cat.children
          li= child.name

Which did nothing obviously because I'm returning data from the async query.exec().then() chain. 显然没有做任何事情,因为我从异步query.exec().then()链返回data I couldn't figure out how to handle calling async from a view. 我不知道如何从视图处理异步调用。 I figured functions stored in app.locals had to be syncronous which APOC isn't friendly too and isn't ideal for data queries anyhow. 我发现存储在app.locals函数必须是同步的,这对APOC也不友好,并且无论如何也不是理想的数据查询方法。 And so I wound up with the following which works but isn't ideal: 因此,我总结了以下可行但不理想的方法:

//app.js
app.use(function(req,res,next){
  var query = apoc.query(
    'MATCH (c:Category)-[o:CHILD_OF]->(m:Menu {url: "cat-menu"}) \
      OPTIONAL MATCH (c2:Category)-[o2:CHILD_OF]->(c) \
      WITH c, c2, o, o2 \
      ORDER BY o2.order, c2.name \
      WITH \
        { \
          name: c.name, \
          url: c.url, \
          children: collect(c2),\
          order: o.order \
        } AS rows \
      ORDER BY rows.order \
      RETURN collect(rows)'
  );
  //console.log(query.statements);
  query.exec().then(function (qres) {
    var data = qres[0]['data'][0]['row'][0];
    console.log(util.inspect(data,false,null));
    res.locals.catMenuQuery = data;
    next();
  }, function (fail) {
    //console.log(fail)
    next();
  });
})

//view.pug
ul#cat-menu.in
  each cat in catMenuQuery
    li(class= cat.url)
      h1= cat.name
      ul
        each child in cat.children
          li= child.name

This is going to call every query for every menu on every page, regardless of whether that menu is on the page or not. 这将为每个页面上的每个菜单调用每个查询,而不管该菜单是否在页面上。 So my question is this: 所以我的问题是这样的:

Is there a way I can get the first version where I call the function inside the view working, or is there another elegant solution that will make sure only the functions that are needed by the views being rendered will be called? 有没有办法让我获得在视图内部调用函数的第一个版本,还是有另一种优雅的解决方案来确保仅调用呈现视图所需的函数?

At the end of the day overhead doesn't matter a great deal because it's just for an in-house prototype job. 归根结底,开销并不重要,因为这只是内部原型工作。 But I'm sure there's an elegant solution out there, and it would be great if I could restructure it to call a function like getMenu('cat-menu') from the views to save having a bunch of functions sitting in app.locals . 但是我敢肯定那里有一个优雅的解决方案,如果我可以将其重组以从视图中调用诸如getMenu('cat-menu')之类的函数以节省一堆位于app.locals的函数,那将是app.locals

I'm sure there's a simple elegant solution somewhere, but I'm back in node async land for the first time in a while and I'm stumped. 我敢肯定某个地方有一个简单而优雅的解决方案,但是一段时间以来我第一次回到节点异步域,这让我很困惑。

I wound up learning to use React and the Flux Architecture. 我结束了学习使用React和Flux Architecture的学习。 It's more or less built for what I was trying to accomplish where Express vanilla renderer isn't well equipped for it. 它或多或少是为在Express Vanilla渲染器功能不完善的情况下试图完成的工作而构建的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM