播放2.x:如何使用公共按钮发出AJAX请求

时间:2012-06-21 06:58:36

标签: javascript java ajax routes playframework-2.0

所以我之前已成功获得ajax请求,但我总是不得不使用表单,然后在提交结束时返回false,这样它就不会刷新页面。

我最近刚刚将我的javascript移动到一个单独的文件中,这导致我的@命令失败。因此,我不知道如何设置我的路线?

HTML:

<button id="saveAsDefaultButton">Save as default</button>

Playframework java代码:

public static Result saveDefaultPhoneForUser(String handset) {
    User currentUser = User.findByName(session("name"));
    currentUser.lastControlledHandset = theHandset;
    currentUser.save();
    return ok();
}

路线:

POST    /                           controllers.Application.saveDefaultPhoneForUser(handset : String)

的javascript:

$('#saveAsDefaultButton').click(function(evt) {
        $('#errors').hide();
        $.ajax({
            type : 'POST',
            url : "controllers.Application.saveDefaultPhoneForUser",
            data : $('#controlledPhone option:selected').text(),
            dataType : "text",
            success : function(data) {
                //setError('Call succedded');
                //$('#test1').attr("src", data)
            },
            error : function(data) {
                setError('Make call failed');
            }
        });
        return false;
    });

我确定有办法做到这一点我只是没有找到任何运气。任何帮助都很大的帮助。

5 个答案:

答案 0 :(得分:122)

对于这项工作,您应该使用javascriptRoutes,因为它会根据您的routes.conf生成正确的JS路径。您将在Zentask sample

中找到使用示例

无论如何,现在您可以通过将url更改为

来修复您的AJAX调用
url : '@routes.Application.saveDefaultPhoneForUser()',

这种方式要求它将整个JS放在模板中,这是错误的。它甚至可以移动到单独的JS文件中,并且可以使用javascriptRoutes。

<强> 更多...

javascriptRoutes 在官方文档中没有描述 ,但这里是对它的逐步介绍。虽然使用这种方式描述看起来很复杂事实上带来了很多好处。

1。创建公共路径

首先,您需要在conf/routes文件中创建公共路径:

GET     /item/:id     controllers.Application.getItem(id: Long)
POST    /item/new     controllers.Application.newItem
PUT     /item/:id     controllers.Application.updateItem(id: Long)

当然,您需要在Application控制器中创建至少这三个操作:

  • getItem(Long id){ ... }
  • newItem() { ... }
  • updateItem(Long id) { ... }

2。创建一个将常见路由转换为JS

的操作
  • 把它放在某个地方,即。在您的Application控制器
  • 我们称之为javascriptRoutes()

在该操作中,您将指向conf/routes文件中的现有路由

public static Result javascriptRoutes() {
    response().setContentType("text/javascript");
    return ok(
        Routes.javascriptRouter("myJsRoutes",
            routes.javascript.Application.getItem(),
            routes.javascript.Application.newItem(),
            routes.javascript.Application.updateItem(),
            //inside somepackage
            controllers.somepackage.routes.javascript.Application.updateItem()
        )
    );
}

注意: 请勿在括号中设置任何参数。

3。为javascriptRoutes操作创建路线并将其包含在模板中

路线conf/routes

GET     /javascriptRoutes     controllers.Application.javascriptRoutes

<head>

/views/main.scala.html部分中查看
<script type="text/javascript" src='@routes.Application.javascriptRoutes()'></script>

4。在你想要的地方使用javascriptRoutes

从现在起,您可以使用JS中的路由来获取正确的路径,而无需指定urltype。例如,代替:

 $('.getAjaxForThisContainer').click(function(e) {
    var idToGet = $("#someField").val();
    $.ajax({
        type : 'GET',
        url : '@routes.Application.getItem()',
        data : {
            id: idToGet
        },
        success : function(data) {
            // ... some code on success
        }
    });
    return false;
});

您可以使用简化版({2}中的myJsRoutes):

myJsRoutes.controllers.Application.getItem(idToGet).ajax({
    success : function(data) { ... some code ... }
});

myJsRoutes.controllers.Application.newItem().ajax({
    success : function(data) { ... some code ... }
});

等...

  • 您不需要指定type: "POST" - JS路由器将根据conf/routes规则使用正确的方法
  • 您可以使用纯JS中的id语法将记录(或其他参数)的GET设置为PUTroutes-like(或其他方法)
  • 如果您的路线规则包含所有必需的参数,您可以真正最小化您的JS:
路线

GET   /some/:a/:b/:c    controllers.Application.getABC(a: String, b: Integer, c: String)

JS:

myJsRoutes.controllers.Application.getABC("a", 1, "b" ).ajax({});

答案 1 :(得分:8)

我喜欢“老好”的简单方法:

1 在页面中,使用JQuery,

在一些偶数处理程序

 $.get('/giveme', {'arg': value}, function(data) {

                                    window.alert(data);

                                  }
 );

2 在服务器/播放端

2.1路线:GET /giveme controllers.Application.giveme(arg)

2.2 scala行动:

object Application extends Controller { 

      def giveme(arg:String) = Action {
        Ok(Json.toJson("hello," + arg ))
      }

    }

答案 2 :(得分:7)

在打电话时需要注意的事项

Routes.javascriptRouter("myJsRoutes",

路线是从play.Routes导入的,而不是play.api.Routes

当我实现此代码时出现错误,因为我认为它来自api(显然我错了)。 除此之外,一切都很棒〜!!

答案 3 :(得分:2)

有一个更简单的解决方案,使用嵌入式路由器生成Javascript路由器。您可以使用@javascriptRouter帮助程序指令生成Javascript路由器,将以下代码放在html页面头标记内(可能在主要装饰模板中)

<head>
    <title>Saeed Title</title>
    <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
    <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
    <script src="@routes.Assets.at("javascripts/jquery/v1.12.4/jquery.min.js")" type="text/javascript"></script>
    @helper.javascriptRouter("jsRoutes")(
        routes.javascript.MyController.getById,
        routes.javascript.MyController.getByName
    )
</head>

不要担心语法错误(在Intellij中)并且不要在操作名称后使用括号。 现在,您可以在ajax调用代码中使用jsRoutes.controllers.MyController.getById(id)

$.ajax(jsRoutes.controllers.MyController.getById(id))
   .done( /*...*/ )
   .fail( /*...*/ );

或使用jsRoutes.controllers.MyController.getById(id).url获取网址。 more information

答案 4 :(得分:1)

马库斯的答案非常好,所以其他任何有此问题的人都应该能够使用它。

我确实遇到过一个问题,但试图让这个工作花了我一段时间才能开始工作。当我发出我的ajax请求时,它会路由到错误的方法。

这是因为在我的路线文件中我有以下内容:

POST    /                           controllers.Application.makeCall()
POST    /                           controllers.Application.saveDefaultPhoneForUser(handset : String)

通过两个post方法具有相同的位置/。似乎总是去打电话。所以,只要给任何人一个小费,就不要这样做,否则就行不通。

我只需将其更改为:

POST    /                           controllers.Application.makeCall()
POST    /saveDefaultPhoneForUser    controllers.Application.saveDefaultPhoneForUser(handset : String)

希望这有助于某人。