为啥我不能像传递其他变量一样将函数从 Express.js 传递给 EJS?

Posted

技术标签:

【中文标题】为啥我不能像传递其他变量一样将函数从 Express.js 传递给 EJS?【英文标题】:Why can't I pass functions from Express.js to EJS like I pass other variables?为什么我不能像传递其他变量一样将函数从 Express.js 传递给 EJS? 【发布时间】:2020-08-24 00:10:38 【问题描述】:

我正在使用Express、EJS 和 MongoDB 开发 blogging application(单击链接以查看 GitHub 存储库)。

尝试对帖子进行分页时,我遇到了将 newerPostsolderPosts 传递给视图的问题。我像 posts 变量(和其他变量)一样传递它们:

exports.getPosts = async (req, res, next) => 
    //pagination params
    var perPage = 10;
    var currPage = req.body.page ? parseInt(req.body.page) : 1;

    const newerPosts = function() 
        currPage = currPage + 1;
        console.log(currPage);
    

    const olderPosts = function() 
        currPage = currPage - 1;
        console.log(currPage);
    

    const posts = await Post.find(, (err, posts) => 
            if (err) 
                console.log('Error: ', err);
             else 
                res.render('default/index', 
                    moment: moment,
                    layout: 'default/layout',
                    website_name: 'MEAN Blog',
                    page_heading: 'XPress News',
                    page_subheading: 'A MEAN Stack Blogging Application',
                    posts: posts,
                    newerPosts: newerPosts,
                    olderPosts: olderPosts
                );
            
        )
        .sort(
            created_at: -1
        )
        .skip((currPage - 1) * perPage)
        .limit(perPage)
        .populate('category');
;

在视图中:

    <div class="px-1">
        <a class="btn btn-primary" href="#" onclick=<%="olderPosts()"%>>&larr; Older Posts</a>
    </div>

     <div class="px-1">
        <a class="btn btn-primary" href="#" onclick=<%="newerPosts()"%>>Newer Posts &rarr;</a>
     </div>

然而,我从浏览器收到了Uncaught ReferenceError: newerPosts is not defined 错误消息。

我做错了什么? 最接近的可行替代方案是什么?

【问题讨论】:

【参考方案1】:

您可以执行以下操作: 新建一个名为functions.ejs的ejs文件:

<script>
  function test()console.log(1)
</script>

然后在您正在渲染的模板中使用&lt;%- include('functions'); %&gt;。在开始时使用它,以便在调用它时定义函数。

在对应的路由中,使用:

res.render('default/index', 
  ...,
  name: 'test'
);

在你的模板里面可以做以下事情:

<button onclick="<%=name%>()"> <%= btnText %> </button>

但是,当我查看您要传递的函数时,我看到您想使用currPage = currPage + 1; 更改应用程序的状态。这不会起作用,因为一旦页面被渲染,html 中就不再有对currPage 的引用,因为到那时一切都是静态的 html。

如果你想改变页面等,你需要实现一些前端逻辑。

【讨论】:

我可以通过 Ajax 加载它们。 是的,你可以这样做,但它会增加太多的开销。即使从架构的角度来看,我也不推荐它,因为您会将视图逻辑与控制器/模型逻辑混合在一起。 您会推荐什么替代方案(如果可能,请提供示例链接)? 请帮我解决 this 的问题。谢谢!【参考方案2】:

检查这个:

const posts = await Post.find(, (err, posts) => 
xxxx ... res.render()
)

我认为这里你需要对 Promise 的使用逻辑做一些改变...... 想一想——如果出现错误会发生什么?你在哪里处理? 更有趣的是——在承诺返回结果之后——你在哪里退出你的函数? ...

【讨论】:

以上是关于为啥我不能像传递其他变量一样将函数从 Express.js 传递给 EJS?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Java 方法不能更改传递的变量? [复制]

为啥我不能将字符串传递给函数 GetDriveTypesA()?

为啥我们不能通过值传递数组来函数?

为啥我不能像这样覆盖变量的值?

为啥我不能将模板函数指针传递给可变参数函数?

为啥使用类变量的这段代码不能像在 Java 中那样工作? [复制]