E js переменная стойкость? - PullRequest
1 голос
/ 23 апреля 2020

У меня есть маршрут express, который фильтрует месяц поста в блоге и возвращает месяцы:

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 в точности соответствует ожиданиям и показывает только блог за апрель.

Но я ожидал, что маршрут localhost:3000 выдаст ошибку, потому что он не проходит фильтр переменная, но она показывает любой месяц, который я выбрал в предыдущем фильтре маршрута.

Только когда я завершаю работу сервера Nodejs и пытаюсь go к маршруту по умолчанию, я получаю:

фильтр не определен

Но если я go до localhost:3000/months/?month=April, а затем go вернемся к `` localhost: 3000`, он отлично загружается с месяцем апреля.

Разве не стоит делиться шаблонами между разными маршрутами? Как это возможно?

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Вам нужно объявить фильтр и передать значение по умолчанию, иначе ваш рендерер не удастся.

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);
1 голос
/ 29 апреля 2020

Шаблон кэшируется при первом вызове. Вы можете попробовать этот ответ , чтобы отключить кэш представления в express -

router.disable('view cache');

Другие варианты перечислены в e js вики -

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

или вы можете попробовать отключить в e js с параметром дополнительных опций -

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