用 Pug 迭代一个对象

问题描述 投票:0回答:1

从 app.js 传递一个对象给 Pug

router.get('/', getMenuList, function (req, res, next) {
  res.render('menu_items', {
   title: 'The Weekly Menu',
   message: 'The List',
   dataset
  });
});

数据集看起来像

menu_date   dish_name         Display
2018-10-01  Fish              2018-10-01: Fish
2018-10-01  Green Beans       2018-10-01: Green Beans with Mushrooms and cream
2018-10-02  Out To Dinner     2018-10-02: Out To Dinner
2018-10-03  Oysters           2018-10-03: Oysters an the half shell
2018-10-03  Sauce Mignette    2018-10-03: Sauce Mignette

我想在 HTML 上显示的是像这样的嵌套列表

2018-10-01
       Fish
       Green Beans
2018-10-02
       Out to diner
2018-10-03
       Oysters
       Sauce Mignette

我的 PUG 代码如下遍历对象,但我不知道如何获取嵌套列表

extends layout

block content
    h2= title
    -var wtf = dataset.length
    -var n = 0
    h1= message
    each item in dataset
        ul
            li #{item.Menu_Date}

下面贴出写html页面的app.js。代码很难看。不擅长使用 javascript、HTML 或 CSS。

    //submit
    var express = require('express');  
    var bodyParser = require('body-parser');  
    var app = express();  
    app.use(bodyParser.json());
    var tedious = require('tedious');
    var Promise = require('promise');
    app.use(bodyParser.urlencoded({ extended: false }));
    var path = require('path');
    var fs = require('fs');  
    
    var router = express.Router();
    var menu_data = [];    
    var menu = [];
    
    app.engine('pug', require('pug').__express);
    app.set('views', path.join(__dirname, 'views'));  
    app.set('view engine', 'pug');
    
    app.use(router);  
    app.use(express.static(path.join(__dirname, 'public')));
    
    
    router.get('/', getMenuList, function (req, res, next) {
         var item = [];
         for(var row of menu_data ){
           if(menu.length == 0) {
             var newItem = {Date: row.MenuDate, Items: item};
                      
             menu.push(newItem);            
           }
           if(row.MenuDate != menu[menu.length -1].Date) {
            
            item = [];
             
             var newItem = {Date: row.MenuDate, Items: item};
             menu.push(newItem);
           }
           var newDish = {Dish: row.Item};
           
           menu[menu.length -1].Items.push(row.Item);
          /* var i = 0;
           while(i < menu[menu.length -1].Items.length) {
             console.log( menu[menu.length -1].Items[i]);
             i++;
           }
           */           
         }
         
         fs.writeFileSync('./views/message.html', '<!DOCTYPE html><html><head><title>The Weekly Menu</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body>', 'utf8', function(err){
          if (err) throw err;
         });
         fs.appendFileSync('./views/message.html', '<h1>Why the drama</h1>', function(err){
           if (err) throw err;
         });
        for(index = 0; index < menu.length ; index++ ) {
            //console.log(menu[index].Date);
            if(index ===0){
              fs.appendFileSync('./views/message.html', '\r\n<ul>', function(err){
                if(err) throw err;
              });
            }
            fs.appendFileSync('./views/message.html', '\r\n<li>'  + menu[index].Date + '</li>', function(err){
              if(err) throw err;
            });
    
                for(newindex = 0; newindex < menu[index].Items.length; newindex++) {
                    //console.log(menu[index].Items[newindex])
                    if(newindex === 0 ){
                    fs.appendFileSync('./views/message.html','\r\n<ul>', function(err){
                      if(err) throw err;
                      });
                    }
                    fs.appendFileSync('./views/message.html', '\r\n<li> ' + menu[index].Items[newindex] + '</li>', function(err){
                      if(err) throw err;
                      });
                  }
                  fs.appendFileSync('./views/message.html', '\r\n</ul', function(err){
                    if(err) throw err;
                  });
          }  // end of outer loop
    
          fs.appendFileSync('./views/message.html', '\r\n</ul>\r\n\<a href=\"http://localhost:3030/index\"> Input Menu Items</a>\r\n</body>\r\n</html>', function(err){
            if(err) throw err;
          });
                    
       /* res.render('menu_items', {
          title: 'The Weekly Menu',
          message: 'The List',
          menu_data,
          menu
         
      }); */
    
       res.sendfile('./views/message.html');
    });
    
    router.get('/index', function(req, res) {
        res.render('index')
    });
    
    router.post('/update',submitMenuItem, function (req, res) {  
          var menu_data = req.body.menuDate;
          var description = req.body.theItem;
          
        res.render('update', {
            title: 'All Quiet on the Western Front',
            menuDate: menu_data,
            MenuItem: description    
        });
    });
    
    // end of submitMenuItem
    
    function getMenuList( req, res, next) {
        var promise = new Promise(function(fulfill, reject){      
        var Connection = require('tedious').Connection;
        var Request = require('tedious').Request;
        var config = JSON.parse(fs.readFileSync('./config/config.json', 'utf8'));
        var connection = new Connection(config);
        
        connection.on('connect', function (err) {
                if (err) {
                  console.log(err);
             } else {
                  executeStatement();
             }
        });
       /* function MenuItem(Menu_Date, Name, Display)
        {
          this.Menu_Data = Menu_Date;
          this.Name = Name;
          this.Display = Display;
        }  */
        
        function executeStatement() {
             var sql = "select dt_ofItem ,dish_name  FROM LA_COUNTY.dbo.mn_items order by dt_ofItem"; 
            
             var Request = require('tedious').Request;
             request = new Request(sql, function (err, rowCount) {
                  if (err) {
                       reject(err);
                  } else {
                      if(rowCount < 1) {
                          callback(null, false);
                      }
                      else {
                       fulfill(menu_data);
                      }
                  }
             });
           
             request.on('row', function (columns) {
                 var Menu_Date = ""
                  columns.forEach(function (column) {
                      
                      if(column.metadata.colName=== "dt_ofItem"){
                          
                          Menu_Date = column.value.toDateString();
                          
                       }
                      if(column.metadata.colName==="dish_name") {
                          //console.log(column.value);
                          //console.log('WTF');
                      //var item = new MenuItem(Menu_Date, column.value, Menu_Date + ": " + column.value);
                      var menu_stuff = {
                        MenuDate: Menu_Date,
                        Item: column.value  
                    };
                      menu_data.push(menu_stuff);
                          //menu_data.push("Date" Menu_Date ,"Item" column.value );
                          //item = null;
                      }
                  });                  
             });
                  
             request.on('doneProc', function (rowCount, more, returnStatus, rows) {
                  next(null, rows);
                  connection.close()

                 // console.log(menu_data[0].MenuDate);

                  menu_data = [];
    
             });
    
             connection.execSql(request);
        }
        });
    }  // end getclients
    
    
    
    function submitMenuItem( req, res, next) {
    var menu_date = req.body.menuDate;
    var description = req.body.theItem;
        
    var Connection = require('tedious').Connection;
    
    var config = JSON.parse(fs.readFileSync('./config/config.json', 'utf8'));
    
     var connection = new Connection(config);
    
      var connection = new Connection(config);
    
      connection.on('connect', function(err) {
    
          executeStatement();
        });

      function executeStatement() {
        var sql = "insert LA_County.dbo.mn_items (dt_ofItem, dish_name) values ('" + menu_date + "','" + description + "')"
        var Request = require('tedious').Request;
        request = new Request(sql, function(err, rowCount) {
          if (err) {
            reject(err);
          } else {
            if(rowCount < 1) {
                callback (null, false);
          }
          else {
              fulfill(menu_date);
          }
        }
        });
      
        request.on('row', function(columns) {
          columns.forEach(function(column) {
            //console.log(column.value);
          });
        });
        
        request.on('doneProc', function (rowCount, more, returnStatus, rows) {
            next(null, rows);
    
                connection.close()
             });  

        connection.execSql(request);
      }    
    
    } // end of submitMenuItem

这里是PUG代码。我非常非常不确定

extends layout

block content
    h2= title
    -var wtf = menu_data.length
    //h1 #{wtf}
    -var n = 0
    h1= message
    ul
        while n < wtf
            li= menu_data[n++].MenuDate



    ul
        each entry in menu
            li= entry.Date
            -var i = entry.Items.length
            h3 #{i}
            -var q = 0
            ul
                each dish in entry.Items
                    li dish
                //while q <  i
                    //li= entry.Items[q]
            
            
    a(href='http://localhost:3030/index') Input Menu Items
    
        app.listen(3030);  
        module.exports = app;  

要获得更完整的视图,代码在 GIT 上

对不起,如果我没有按照 Hoyle 的说法做这些帖子。

pug
1个回答
3
投票

为了使这项工作正常进行,您需要在路线中稍微调整一下数据。

我们将创建一个对象数组,其中日期作为键,一个菜肴数组作为每个日期的属性。我们想使用数组作为核心对象,因为不能保证迭代 JavaScript 对象的键顺序,但它在数组中。

这样做将使 Pug 模板更容易迭代并为您提供所需的嵌套列表。将复杂的转换逻辑添加到模板本身并不是一个好主意,路由是存储它的最佳位置。

这是我们想要动态构建的 pug 友好数组:

[
    {
      "date": "2018-10-01",
      "items": ["Fish", "Green Beans"]
    },
    {
      "date": "2018-10-02",
      "items": ["Out to Diner"]
    },
    {
      "date": "2018-10-03",
      "items": ["Oysters", "Sauce Mignette"]
    }
]

这里是如何转换它(我假设你的数据集变量在这里排序,如果没有那么你需要使用不同的算法来做到这一点):

var menu = [];

for(var row of dataset){

  // see if the date on the current row is the same as the last date in the menu array
  if( row.menu_date != menu[menu.length - 1].date ) {

    // add new object to the end of the array
    menu.push({
      "date": row.menu_date,
      "items": []
    });

  }

  // add item from current row to the end of the array in the last menu date entry
  menu[menu.length - 1].items.push(row.dish_name);

}

将菜单变量而不是数据集传递给 res.render 函数,然后模板可以像这样迭代这个对象:

ul
  each entry in menu
    li= entry.date
      ul
        each item in entry.items
          li= item

如果您需要更改此处的逻辑(添加字段、更改列表格式等)或调试您的代码,保持模板更简单会非常容易。

© www.soinside.com 2019 - 2024. All rights reserved.