Ejs变量持久性



我有一个快速路线,它过滤博客文章的月份并返回月份:

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);

最新更新