Node.js按分类渲染文章:实现每个分类仅展示3篇的需求求助
解决每个分类仅显示3篇文章的问题
嘿,我来帮你搞定这个问题!你现在的写法是把所有分类和所有文章一股脑传给模板,在模板里筛选时很容易绕进循环困境里。其实有两种靠谱的解决思路,我给你拆解清楚:
方法一:后端预处理数据(推荐)
这种方式更高效,后端先把每个分类对应的前3篇文章整理好,再传给模板,模板只需要做简单渲染就行,完全不会有循环问题。
修改你的app.js首页路由代码:
app.get('/', async function(req, res) { try { // 查询所有分类 const categories = await Category.find({}).lean(); // 给每个分类匹配对应的前3篇文章 const categoriesWithArticles = await Promise.all( categories.map(async category => { // 假设你的Article模型用category字段关联分类ID const articles = await Article.find({ category: category._id }) .sort({ createdAt: -1 }) // 按创建时间倒序,取最新3篇 .limit(3) .lean(); return { ...category, articles }; }) ); // 把整理好的数据传给模板 res.render("index", { categories: categoriesWithArticles }); } catch (err) { console.error(err); res.status(500).send('服务器出错啦'); } });
然后修改index.hbs模板,直接遍历分类和对应文章:
{{#each categories}} <div class="category-block"> <h3>{{name}}</h3> <!-- 假设分类有name字段 --> <ul> {{#each articles}} <li> <a href="/article/{{_id}}">{{title}}</a> <!-- 假设文章有title和_id字段 --> </li> {{/each}} </ul> </div> {{/each}}
方法二:模板端用Handlebars辅助函数处理
如果不想改动后端逻辑,也可以给Handlebars注册一个辅助函数,用来筛选指定分类的文章并限制数量。
先在app.js里注册辅助函数:
const hbs = require('hbs'); // 注册筛选文章的辅助函数 hbs.registerHelper('filterArticlesByCategory', function(articles, categoryId, limit) { return articles .filter(article => article.category.toString() === categoryId.toString()) .slice(0, limit); });
然后在index.hbs模板里使用这个辅助函数:
{{#each categories}} <div class="category-block"> <h3>{{name}}</h3> <ul> {{#each (filterArticlesByCategory ../articles _id 3)}} <li> <a href="/article/{{_id}}">{{title}}</a> </li> {{/each}} </ul> </div> {{/each}}
这里的../articles是用来访问父级上下文的所有文章数组,因为在each categories循环里,当前上下文是单个分类对象。
不过这种方法的缺点是会把所有文章都传给前端,数据冗余,性能不如后端预处理的方式。
内容的提问来源于stack exchange,提问作者Nedeljko Ružić
相关产品推荐
相关产品推荐

