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

Javascript Play 2.x:如何使用公共按钮发出AJAX请求,javascript,java,ajax,routes,playframework-2.0,Javascript,Java,Ajax,Routes,Playframework 2.0,因此,我以前成功地让AJAX请求工作,但我始终必须使用表单,然后在提交结束时返回false,这样它就不会刷新页面 我最近还将JavaScript移到了一个单独的文件中,这导致@commands失败。正因为如此,我不知道如何设置我的URL到我的路线 HTML: 路线: POST / controllers.Application.saveDefaultPhoneForUser(handset : String) javascript: $

因此,我以前成功地让AJAX请求工作,但我始终必须使用表单,然后在提交结束时返回false,这样它就不会刷新页面

我最近还将JavaScript移到了一个单独的文件中,这导致@commands失败。正因为如此,我不知道如何设置我的URL到我的路线

HTML:

路线:

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;
    });

我肯定有办法做到这一点,但我只是没有运气找到任何东西。

对于这项工作,您应该使用
javascriptRoutes
,因为它根据routes.conf生成正确的JS路径。您将在Zentash中找到用法示例

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

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
controller中至少创建这三个操作:

  • getItem(长id){…}
  • newItem(){…}
  • updateItem(长id){…}
2.创建将公共路由转换为JS的操作
  • 将其放置在某个位置,即在
    应用程序中
    控制器中
  • 我们称之为
    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
查看
部分
/views/main.scala.html

<script type="text/javascript" src='@routes.Application.javascriptRoutes()'></script>
您可以使用简化版本(
myJsRoutes
第2点):

等等

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

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


马库斯的回答很好,所以任何有这个问题的人都应该能够使用这个

我确实有一个问题,虽然当试图让这个工作,这花了我一点时间开始工作。当我发出ajax请求时,它被路由到错误的方法

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

POST    /                           controllers.Application.makeCall()
POST    /                           controllers.Application.saveDefaultPhoneForUser(handset : String)
通过使用具有相同位置/的两个post方法。它似乎总是去打电话。所以,给任何人一个提示,不要这样做,否则它不会起作用

我只需要将其更改为:

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

希望这对某人有所帮助。

需要注意的事情。。。打电话的时候

Routes.javascriptRouter("myJsRoutes",
路由是从play.Routes导入的,而不是play.api.Routes

我在实现这段代码时出错,因为我假设它来自api(显然我错了)。 除此之外,一切都很好~

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

1在页面中,使用JQuery

在一些偶数处理器内部

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

                                    window.alert(data);

                                  }
 );
2在服务器/播放端

2.1路由:
GET/giveme控制器.应用程序.giveme(arg)

2.2 scala行动:

object Application extends Controller { 

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

    }

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

或者使用
jsRoutes.controllers.MyController.getById(id).url
获取url。
.

非常感谢马库斯。我确实看过zen任务示例,但由于我刚刚回到web开发中,所以刷新了我的html、css和javascript知识。当那个例子是用咖啡脚本写的时候,我有点犹豫了。当我尝试它时,我无法让它工作。另外,marcus只是一个简单的问题,如果在我的操作中我做了一些服务器端验证,然后返回badRequest(“发送的数据不正确”);成功后,我还将错误捕获放在javascript中:error:function(data){setError('Make call failed');}我如何访问传递的字符串。当我将错误消息放入接收时,得到的结果是“object[object]”。或者你知道我调试/检查这些信息的方法吗?官方文档中的javascript路由:不是每个人都想使用CoffeScript。。这就是这个官方文档的内容。@biesior从回答中我不明白的一件事是,使用
url:'@routes.Application.getItem()',
的ajax调用在理论上是否可行。我在这里试过,但没有成功,play指责论点缺失。我之所以问这个问题,是因为我正在考虑以一种类似于正常做法的方式将其与jqGrid相结合,如果
路由
文件包含两个具有相同方法的规则,则只会首先使用路径。我可以在
函数(数据)
中使用多个参数吗。像
函数(数据,数据1)
myJsRoutes.controllers.Application.getABC("a", 1, "b" ).ajax({});
POST    /                           controllers.Application.makeCall()
POST    /                           controllers.Application.saveDefaultPhoneForUser(handset : String)
POST    /                           controllers.Application.makeCall()
POST    /saveDefaultPhoneForUser    controllers.Application.saveDefaultPhoneForUser(handset : String)
Routes.javascriptRouter("myJsRoutes",
 $.get('/giveme', {'arg': value}, function(data) {

                                    window.alert(data);

                                  }
 );
object Application extends Controller { 

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

    }
<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>
$.ajax(jsRoutes.controllers.MyController.getById(id))
   .done( /*...*/ )
   .fail( /*...*/ );