[英]Ajax through javascript route, controller should return json and return html page
Environment : scala 2.10, play 2.1.1, eclipse 4.2 环境:scala 2.10,play 2.1.1,eclipse 4.2
Use case : the user click on a link figuring an object (game) in the database. 用例:用户单击确定数据库中对象(游戏)的链接。 An ajax request is sent through Javascript Route to a controller, which load the game data, convert it to json and send it back to view.
Ajax请求通过Javascript Route发送到控制器,该控制器加载游戏数据,将其转换为json并发送回视图。 The ajax success callback print the game title into a div.
Ajax成功回调将游戏标题打印到div中。
Problem: i dont get a json, but the a html page (the page from which the ajax request s sent). 问题:我没有得到json,但是有一个html页面(从其发送ajax请求的页面)。
I suspect the problem is in the router : i put a print("route") in the javascript route action and a print("load game") in load game action. 我怀疑问题出在路由器:我在javascript路线操作中放置了print(“ route”),在载入游戏操作中放置了print(“ load game”)。 The "route" is displayed in console, but not the "load game".
“路线”显示在控制台中,但不显示“加载游戏”。 It may also come from my loadGame(id) route, but i dont see how i should set it.
它也可能来自我的loadGame(id)路线,但我不知道如何设置它。
Here is my code. 这是我的代码。
Routes: 路线:
# 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)
View: 视图:
<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>
ApplicationController with javascript route: ... 具有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")
}
}
GameController with loadGame(id) method: 带有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)
}
}
Game model: 游戏模型:
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))
)
}
}
In your routes
file, you have to routes matching the same URL : 在
routes
文件中,您必须匹配相同URL的路由:
# Library
GET /library/:id controllers.UserController.library(id: Long)
GET /library/:id controllers.GameController.loadGame(id: Long)
When your browser request the /library/123
url, Play will try the routes in the order of declaration and will match the first one, calling the controllers.UserController.library()
Action. 当您的浏览器请求
/library/123
网址时,Play会按照声明的顺序尝试路由,并匹配第一个路由,并调用controllers.UserController.library()
操作。 This is probably why you get a full HMTL page. 这可能就是为什么获得完整的HMTL页面的原因。
Try to define a different URL for the second route (the one returning JSON) and Play will be able to match the correct Action. 尝试为第二条路线(返回JSON的那个)定义一个不同的URL,然后Play就能匹配正确的Action。
Ex : 例如:
GET /library/:id controllers.UserController.library(id: Long)
GET /gameData/:id controllers.GameController.loadGame(id: Long)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.