0

环境: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))
      )
  }
}
4

1 回答 1

0

在您的routes文件中,您必须路由匹配相同的 URL:

# Library
GET     /library/:id                    controllers.UserController.library(id: Long)
GET     /library/:id                    controllers.GameController.loadGame(id: Long)

当您的浏览器请求/library/123url 时,Play 将按照声明的顺序尝试路由并匹配第一个,调用controllers.UserController.library()Action。这可能就是您获得完整 HMTL 页面的原因。

尝试为第二个路由(返回 JSON 的那个)定义一个不同的 URL,Play 将能够匹配正确的 Action。

前任 :

GET     /library/:id                    controllers.UserController.library(id: Long)
GET     /gameData/:id                   controllers.GameController.loadGame(id: Long)
于 2013-06-05T19:04:23.233 回答