You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala Play中无需重载整页更新投票计数器的实现方法

基于Play Twirl实现点赞计数同步(无Ajax/JS方案)

首先明确:不借助JavaScript或Ajax的话,没法做到无刷新的局部更新——Twirl是服务器端模板引擎,所有渲染工作都在服务端完成,客户端拿到的是静态HTML,没有动态修改页面内容的能力。不过可以用Twirl参数优化整页重载的实现,让计数同步更简洁。

具体实现步骤

1. 内存维护帖子数据

用单例对象存储帖子及点赞/点踩计数:

object PostStore {
  private var posts: Map[Long, (String, Int, Int)] = Map(
    1L -> ("我的第一篇帖子", 0, 0) // (标题, 点赞数, 点踩数)
  )

  def getPost(id: Long): Option[(String, Int, Int)] = posts.get(id)
  def upvote(id: Long): Unit = {
    posts = posts.updated(id, posts(id) match { case (t, u, d) => (t, u+1, d) })
  }
  def downvote(id: Long): Unit = {
    posts = posts.updated(id, posts(id) match { case (t, u, d) => (t, u, d+1) })
  }
}

2. 控制器处理投票请求

投票操作完成后,重定向回帖子详情页,将更新后的计数传入Twirl模板:

class PostController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
  def showPost(id: Long) = Action {
    PostStore.getPost(id) match {
      case Some((title, upvotes, downvotes)) =>
        Ok(views.html.postDetail(id, title, upvotes, downvotes))
      case None => NotFound("帖子不存在")
    }
  }

  def upvotePost(id: Long) = Action {
    PostStore.upvote(id)
    Redirect(routes.PostController.showPost(id))
  }

  def downvotePost(id: Long) = Action {
    PostStore.downvote(id)
    Redirect(routes.PostController.showPost(id))
  }
}

3. Twirl模板渲染计数

直接使用控制器传递的参数渲染投票按钮和实时计数:

@(postId: Long, title: String, upvotes: Int, downvotes: Int)

<h1>@title</h1>
<div class="vote-controls">
  <form action="@routes.PostController.upvotePost(postId)" method="post">
    <button type="submit">点赞 (@upvotes)</button>
  </form>
  <form action="@routes.PostController.downvotePost(postId)" method="post">
    <button type="submit">点踩 (@downvotes)</button>
  </form>
</div>

关键说明

  • 这种方式本质仍是整页刷新,但通过Twirl参数直接绑定最新计数,代码逻辑更清晰,避免了手动拼接HTML的冗余操作。
  • 如果想要实现无刷新的局部更新,必须结合JavaScript配合Ajax或WebSocket——毕竟客户端需要主动获取最新计数并修改页面元素,这是纯服务器端渲染无法实现的。

内容的提问来源于stack exchange,提问作者nTn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:40:43