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

Play框架视图中如何调用路由并嵌入其返回的HTML?

解决方案

针对你在Play框架视图中嵌入控制器路由返回的评论HTML需求,以下是几种可行方案:


方案1:前端AJAX异步加载(推荐)

这是最符合Play异步非阻塞设计的方案,页面加载后通过JavaScript请求评论接口,将结果插入到对应帖子的末尾:

  1. 修改视图,预留评论容器
    在每个帖子的HTML结构末尾添加评论容器:
@for(answer <- answers) {
  <li class="list-group-item bg-dark">
    <!-- 原帖子内容 -->
    <div id="comments-@answer.id" class="comment-section"></div>
  </li>
}
  1. 添加异步加载脚本
    在视图末尾加入JavaScript代码,页面加载完成后自动请求评论:
document.addEventListener('DOMContentLoaded', () => {
  document.querySelectorAll('.comment-section').forEach(container => {
    const answerId = container.id.split('-')[1];
    fetch(`/post/${answerId}/comments`)
      .then(res => res.text())
      .then(html => container.innerHTML = html)
      .catch(err => console.error('评论加载失败:', err));
  });
});

方案2:服务器端预加载评论(推荐,无前端依赖)

如果不想用AJAX,可以在父控制器中批量预加载所有帖子的评论,直接传递给视图渲染:

  1. 修改父控制器逻辑
    获取帖子列表的同时,批量获取对应评论:
def showAnswers = Action.async { implicit request =>
  AnswerService.getAllAnswers().flatMap { answers =>
    // 批量获取每个帖子的评论,返回(帖子ID -> 评论列表)的Future集合
    val commentFutures = answers.map(ans => 
      CommentService.getCommentsByAnswerId(ans.id).map(ans.id -> _)
    )
    // 等待所有评论请求完成,转为Map结构
    Future.sequence(commentFutures).map { commentPairs =>
      val commentMap = commentPairs.toMap
      Ok(views.html.answers(answers, commentMap))
    }
  }
}
  1. 更新视图参数与渲染
    修改视图接收评论映射,直接渲染评论视图:
@(answers: Set[Answer], commentMap: Map[Long, Set[Comment]])(implicit request: RequestHeader, flash : Flash)
{
  <!-- 原帖子循环 -->
  @for(answer <- answers) {
    <!-- 原帖子内容 -->
    @views.html.comments(commentMap.getOrElse(answer.id, Set.empty))
  }
}

方案3:服务器端同步调用(不推荐,性能风险)

如果必须在视图中直接调用控制器动作,可以通过注入控制器实例并同步获取结果,但这种方式会阻塞请求线程,高并发场景下不建议使用:

  1. 修改视图参数,注入控制器与执行上下文
@(answers: Set[Answer])(implicit request: RequestHeader, flash: Flash, postsController: PostsController, ec: ExecutionContext)
  1. 在循环中调用动作并渲染
@for(answer <- answers) {
  <!-- 原帖子内容 -->
  @{
    import scala.concurrent.Await
    import scala.concurrent.duration._
    // 调用评论动作并同步等待结果
    val commentResult = postsController.answerComments(answer.id)(request)
    val htmlContent = Await.result(commentResult.map(_.body.toString), 5.seconds)
    Html(htmlContent)
  }
}

内容的提问来源于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 09:01:18