下拉框的显示问题(Nodejs相关)

下拉框的显示问题(Nodejs相关)

下拉框是ul li的方式,不过li下面还有一个ul,li所以我在mongo中设计的两张表,它们通过id和fatherid相关联。 自己照着书写了一个数据库的get方法,在尝试显示外层的ul时,ok显示正常。后来尝试开始写个字的下拉框里的内容,之前显示外层ul的时候,我们是传了一个空给get方法查询所有结果,然后遍历它,这里我的想法是这样的,在遍历的for循环中,我可以得到每个外层ul的id,然后去匹配内层ul的fatherid,想法不错,这相当于是在for循环中,不停执行get方法,后来系统报错了。 不知道我说没说明白,如果谁有做过多级的下拉框的显示时,分享一下你们的心得,谢谢了


2 回复

好的,下面是一个关于如何使用Node.js和MongoDB实现多级下拉框显示问题的回答。

下拉框的显示问题(Nodejs相关)

背景

你提到你正在使用ulli标签来构建一个多级下拉菜单,并且你在MongoDB中有两个集合,它们通过idfatherid关联起来。你已经成功地显示了外层的ul,但在尝试显示嵌套的ul时遇到了问题。

解决方案

为了实现多级下拉框,你需要递归地获取数据并将其正确地嵌套。以下是一个简单的解决方案:

  1. 定义模型 假设你有两个集合 categoriessubcategories,其中 categories 包含顶级分类,subcategories 包含子分类,并且它们通过 idfatherid 关联。

  2. 获取数据的方法 使用一个递归函数来获取所有子分类,并将它们嵌套到正确的父分类中。

  3. 前端渲染 使用模板引擎(如EJS或Pug)来渲染最终的HTML结构。

示例代码

1. 定义模型

// models/Category.js
const mongoose = require('mongoose');

const categorySchema = new mongoose.Schema({
    name: String,
    fatherid: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' }
});

module.exports = mongoose.model('Category', categorySchema);

2. 获取数据的方法

// controllers/categoryController.js
const Category = require('../models/Category');

async function getCategories(fatherid = null) {
    const categories = await Category.find({ fatherid });
    for (let category of categories) {
        category.subcategories = await getCategories(category._id);
    }
    return categories;
}

3. 前端渲染

// routes/index.js
const express = require('express');
const router = express.Router();
const categoryController = require('../controllers/categoryController');

router.get('/', async (req, res) => {
    const categories = await categoryController.getCategories();
    res.render('index', { categories });
});
<!-- views/index.ejs -->
<!DOCTYPE html>
<html>
<head>
    <title>Dropdown Menu</title>
</head>
<body>
    <ul id="main-menu">
        <% categories.forEach(category => { %>
            <li><%= category.name %>
                <% if (category.subcategories.length > 0) { %>
                    <ul>
                        <% category.subcategories.forEach(subcategory => { %>
                            <li><%= subcategory.name %></li>
                        <% }) %>
                    </ul>
                <% } %>
            </li>
        <% }) %>
    </ul>
</body>
</html>

总结

通过递归获取所有子分类并将它们嵌套到正确的父分类中,你可以轻松地实现多级下拉菜单。这种方法不仅简洁,而且易于维护。希望这个示例能帮助你解决问题!


从你的描述来看,你想要实现一个多级下拉菜单,并且使用MongoDB来存储这些层级关系。问题在于你在遍历外层<ul>元素时,试图动态获取内层<ul>的内容,导致系统报错。

解决方案

一种常见的做法是先一次性加载所有数据,然后在前端根据需要动态渲染出多级下拉菜单。这样可以避免在遍历过程中频繁调用数据库,提高性能并减少错误。

示例代码

1. 后端(Node.js + Express)

const express = require('express');
const MongoClient = require('mongodb').MongoClient;
const app = express();
const port = 3000;

let db;

app.use(express.json());

MongoClient.connect('mongodb://localhost:27017', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(client => {
    console.log('Connected to Database');
    db = client.db('yourDatabaseName');
  })
  .catch(err => console.error(err));

app.get('/api/menus', (req, res) => {
  db.collection('menus')
    .find()
    .toArray()
    .then(result => {
      res.json(result);
    })
    .catch(err => {
      console.error(err);
      res.status(500).send('Error fetching menus');
    });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

2. 前端(HTML + JavaScript)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Multilevel Dropdown Menu</title>
<style>
  ul { list-style-type: none; padding: 0; }
  ul li { display: inline-block; position: relative; }
  ul ul { display: none; position: absolute; top: 100%; left: 0; }
</style>
</head>
<body>
<ul id="menu"></ul>

<script>
  fetch('/api/menus')
    .then(response => response.json())
    .then(data => {
      const menu = document.getElementById('menu');

      function buildMenu(items) {
        items.forEach(item => {
          const li = document.createElement('li');
          const a = document.createElement('a');
          a.href = '#';
          a.textContent = item.name;
          li.appendChild(a);

          if (item.children && item.children.length > 0) {
            const subMenu = document.createElement('ul');
            buildMenu(item.children);
            li.appendChild(subMenu);
          }

          menu.appendChild(li);
        });
      }

      buildMenu(data);
    })
    .catch(error => console.error('Error:', error));
</script>
</body>
</html>

解释

  1. 后端:我们使用Express框架来创建一个API,该API返回所有菜单项。这包括外层和内层的菜单项。
  2. 前端:我们使用JavaScript的fetch API来获取菜单数据,并递归构建DOM树,以生成多级下拉菜单。

这种方法的好处是只进行一次数据库查询,从而减少了服务器压力,并提高了用户体验。

回到顶部