2014-02-10 26 views
0

默认情况下,当一个人有一个途径是获得一个列表参数与发挥解析AJAX查询querystringbind

GET /list controllers.Application.index(ids: List[Long]) 

玩预计,请求URI看起来像

/list?ids=1&ids=2&ids=3 

但jQuery的动作。 AJAX在默认情况下发送请求作为

/list?ids%5B%5D=1&ids%5B5D=2&ids%5B%5D=3 

Play已经叫做QueryStringBindable可能用于改变这种行为。不是吗?如果它可以用来解决这个问题,那么如何实现可以自定义查询绑定器? 还是有其他解决方案?

回答

1

您最好在Play中使用JavaScript路由支持。

在你的控制器中,添加以下方法

def jsRoutes = Action { implicit request => 
    Ok(Routes.javascriptRouter("jsRoutes")(
    controllers.routes.javascript.Application.index)) 
    .as("text/javascript") 
} 

将其暴露在你的路由文件,即/资产以上/ *文件条目

GET /assets/js/routes  controllers.Application.jsRoutes() 
GET /assets/*file   controllers.Assets.at(path="/public", file) 

标签添加到您的视图来获取它生成的JavaScript

<script src="@controllers.routes.Application.jsRoutes()" type="text/javascript"></script> 

最后,不要使用jQuery来进行AJAX调用,您可以使用一个对象,它是知道的路由需求:

jsRoutes.controllers.Application.index(id1, id2, etc).ajax({ 
     success : function (data, textStatus, jqXHR) { 
     // do something on success 
     }, 
     error: function (jqXHR, textStatus, errorThrown) { 
     // do something on error 
     }, 
     complete: function(jqXHR, textStatus) { 
     // do something on complete 
     } 
    }); 

那里,如果你改变你的指数()航线使用路径参数而不是查询参数这里是一个额外的好处,不需要改变在JavaScript - 中路由对象会为你处理。

参考

斯卡拉:http://www.objectify.be/wordpress/?p=746

的Java:http://www.objectify.be/wordpress/?p=734

编辑:对于单页的应用程序

有您可以使用单页面应用程序两种方法。

1.创建一个控制器,公开你想访问AJAX的每一条路径。例如,对于路线文件

GET /foo  controllers.FooController.foo() 
GET /bar  controllers.BarController.bar() 

你可以有一个(例如,)JsRoutesController控制器,具有如下功能:

def jsRoutes = Action { implicit request => 
    Ok(Routes.javascriptRouter("jsRoutes")(
    controllers.routes.javascript.FooController.foo)), 
    controllers.routes.javascript.BarController.bar)) 
.as("text/javascript") 
} 

更新您的路由

GET /assets/js/routes  controllers.JsRoutesController.jsRoutes() 

,然后访问使用

<script src="/js/routes" type="text/javascript"></script> 

2.的JS对象名在jsRoutes指定它函数(上例中的Routes.javascriptRouter(“jsRoutes”))。每个控制器可以有一个jsRoutes函数,它公开一个特定于控制器的JS路由对象。

在FooController的:

def jsRoutes = Action { implicit request => 
    Ok(Routes.javascriptRouter("fooRoutes")(
    controllers.routes.javascript.FooController.foo)) 
.as("text/javascript") 
} 

在BarController:

def jsRoutes = Action { implicit request => 
    Ok(Routes.javascriptRouter("barRoutes")(
    controllers.routes.javascript.BarController.bar)) 
.as("text/javascript") 
} 

更新你的路由文件

GET /assets/js/foo/routes  controllers.FooController.jsRoutes() 
GET /assets/js/bar/routes  controllers.BarController.jsRoutes() 

而在你的页面

<script src="/js/foo/routes" type="text/javascript"></script> 
<script src="/js/bar/routes" type="text/javascript"></script> 

任何一种方法都不需要播放2的视图图层。

+0

感谢您的详细解答。这个解决方案很有趣,但我们将客户端代码作为基于emberjs的单页JavaScript应用程序开发,并且我们不使用视图元素。所以我们需要在客户端开发期间嘲笑这个jsRoutes。如何轻松实现这一点? – jrabary

+0

2种方式,但细节是必需的;看到更新的答案。 –