环境:scala 2.10,play 2.1.1,eclipse 4.2
用例:用户单击一个链接,该链接表示数据库中的一个对象(游戏)。ajax 请求通过 Javascript 路由发送到控制器,控制器加载游戏数据,将其转换为 json 并将其发送回视图。ajax 成功回调将游戏标题打印到 div 中。
问题:我没有得到一个 json,而是一个 html 页面(发送 ajax 请求的页面)。
我怀疑问题出在路由器上:我在 javascript 路由操作中放置了一个 print("route"),在加载游戏操作中放置了一个 print("load game")。“路线”显示在控制台中,但不显示“加载游戏”。它也可能来自我的 loadGame(id) 路线,但我不知道应该如何设置它。
这是我的代码。
路线:
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Home page
GET / controllers.Application.index
# Javascript routes
GET /javascriptRoutes controllers.Application.javascriptRoutes
# Library
GET /library/:id controllers.UserController.library(id: Long)
GET /library/:id controllers.GameController.loadGame(id: Long)
看法:
<div class="span2">
<ul class="nav nav-pills nav-stacked">
@userGames.map { game =>
<li><a href="#" onclick="displayGameInfo(@game.id)">@game.title</a></li>
}
</ul>
</div>
...
<script>
var successFn = function(data) {
$('#gameInfo').html('');
$("#gameInfo").append('<h4>'+data.title+'</h4>')
}
var errorFn = function(err) {
console.debug("Error of ajax Call");
console.debug(err);
}
ajax1 = {
dataType: 'text',
contentType:'application/json',
success: successFn,
error: errorFn
}
var displayGameInfo = function(id) {
javascriptRoutes.controllers.GameController.loadGame(id)
.ajax(ajax1);
}
</script>
带有 javascript 路由的 ApplicationController:...
object Application extends Controller {
def javascriptRoutes = Action { implicit request =>
import routes.javascript._
println("-=== route ===-")
Ok(
Routes.javascriptRouter("javascriptRoutes")(routes.javascript.GameController.loadGame)
).as("text/javascript")
}
}
带有 loadGame(id) 方法的 GameController:
object GameController extends Controller {
...
// Library
def loadGame(id: Long) = Action(parse.json) { implicit request =>
println("-=== load game ===-")
val mess = Json.toJson(Game.find(id))
Ok(mess)
}
}
游戏模型:
case class Game(id: Long, title: String, description: String, userId: Long)
object Game {
val game = {
get[Long]("id") ~
get[String]("title") ~
get[String]("description") ~
get[Long]("userId") map {
case id~title~description~userId => Game(id, title, description, userId)
}
}
...
def find(id: Long): Game = DB.withConnection { implicit c =>
SQL("select * from game where id = {id}")
.on('id -> id).as(game *).head
}
implicit object GameFormat extends Format[Game] {
def reads(json: JsValue) = JsSuccess(Game(
(json \ "id").as[Long],
(json \ "title").as[String],
(json \ "description").as[String],
(json \ "uid").as[Long]
))
def writes(game: Game) = JsObject(Seq(
"id" -> JsNumber(game.id),
"title" -> JsString(game.title),
"description" -> JsString(game.description),
"userId" -> JsNumber(game.userId))
)
}
}