不是变量持久化吗?

Ejs variable persistence?

我有一个快速路由可以过滤博客的月份 post 和 returns 月份:

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

它 returns 博客 post 按月份过滤。如您所见,我发回了一个过滤器变量,以便在我的模板中显示 header,就像在我的 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 服务器并尝试转到默认路由时,我才会得到:

filter is not defined

但是,如果我转到 localhost:3000/months/?month=April,然后返回到“localhost:3000”,它会在 4 月加载得很好。

在不同的路由之间共享模板不是个好主意吗?这怎么可能?

模板在第一次调用时被缓存。您可以尝试 禁用 express 中的视图缓存 -

router.disable('view cache');

另一种选择是在ejs wiki-

上列出
router.set('view options', {cache: false});

或者您可以尝试使用附加选项参数在 ejs 中禁用 -

res.render("index",{posts:rows,tags:tags}, {cache: false})

您需要声明过滤器并传递一个默认值,否则您的渲染器将失败。

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