我有一个快速路线,它过滤博客文章的月份并返回月份:
router.get("/months", async (req,res)=>{
try{
let posts = await pool.query(`select * from posts
where MonthName(created_at) = '${req.query.month}'`)
console.log(`select * from posts
where MonthName(created_at) = '${req.query.month}'`)
let tags = await pool.query(`Select tagName from tags`)
filter = req.query.month
res.render("index",{posts,tags,filter})
}
catch(err){
console.log(err)
}
})
它返回按月份筛选的博客文章。正如你所看到的,我正在发回一个过滤器变量,以便在我的模板中显示标题,就像在我的index.ejs
文件中一样:
<h2><%= filter %> Blogs</h2>
以便它显示为四月博客或用户选择的的任何过滤器
现在,相同的模板也被默认的索引路由所破坏:
router.get("/", async (req,res)=>{
try{
let rows = await pool.query(`Select userName as author, posts.* from posts
inner join users on users.id = posts.user_id`)
let tags = await pool.query(`Select tagName from tags`)
res.render("index",{posts:rows,tags:tags})
}
catch(err){
console.log(err)
}
})
默认情况下,不应用任何筛选器,甚至不发送筛选器变量。
现在,localhost:3000/months/?month=April
完全不出所料,只显示了4月份的博客。
但我预计localhost:3000
路由会抛出一个错误,因为它没有通过过滤器变量,但它显示了我在上一个路由过滤器中选择的任何月份。
只有当我终止Nodejs服务器并尝试转到默认路由时,我才能得到:
过滤器未定义
但如果我转到localhost:3000/months/?month=April
,然后返回"localhost:3000",它的加载与四月月份的加载一样好。
在不同的路线之间共享模板不是一个好主意吗?这怎么可能?
模板在第一次调用时被缓存。你可以尝试这个答案来禁用express-中的视图缓存
router.disable('view cache');
另一个选项列在ejs wiki-上
router.set('view options', {cache: false});
或者您可以尝试在ejs中使用附加选项参数-禁用
res.render("index",{posts:rows,tags:tags}, {cache: false})
您需要声明filter并传递默认值,否则您的渲染器将失败。
router.get("/months", async (req,res)=> {
try {
let dbQuery = `select * from posts`;
// handle when req.query.month is not passed.
if (req.query.month) {
dbQuery += ` where MonthName(created_at) = '${req.query.month}'`;
}
const posts = await pool.query(dbQuery);
const dbQuery2 = 'Select tagName from tags';
const tags = await pool.query(dbQuery2);
// declare filter here and assign '' when it's not passed request,
// otherwise your render will fail.
const filter = query.month ? query.month : '';
return res.render("index", {posts, tags, filter});
} catch(err){
// pass error to your main error handler.
return next(err);
}
})
此外,我建议您更好地组织代码。
// your common shared logic
async function logic({query, params, body}){
const dbQuery = `select * from posts`;
const posts = await pool.query(dbQuery);
return {posts};
}
function handler(req, res, next) {
logic(req)
.then((result) => {
return res.render("index",result);
})
.catch(next);
}
// you can create separate handlers for each requests
// and use the shared logic in handlers.
router.get("/", handler);
router.get("/months", handler);