Play 框架使用 Ok(...) 编写不加载新页面的 Action

Play framework write Action with Ok(...) that doesn't load new page

播放框架 2.4.x。在我的主页上按下了一个按钮,该按钮通过 Ajax 执行一些代码,并且 return 在按钮下方显示其结果而不加载新页面。结果等待用户在字段中输入一些文本并按 "submit"。这些结果看起来像这样:

<li class="item">
        <div>
            <h3>Email: </h3>
            <a>@email.tail.init</a>
            <h3>Name: </h3>
            <a>@name</a>
        </div>
        <div>
            <h3>Linkedin: </h3>
            <form class="linkedinForm" action="@routes.Application.createLinkedin" method="POST">
                <input type="number" class="id" name="id" value="@id" readonly>
                <input type="text" class="email" name="email" value="@email" />
                <input type="text" class="emailsecondary" name="emailsecondary" value="" />
                <input type="text" class="name" name="email" value="@name" />
                <input type="text" class="linkedin" name="linkedin" value="" />
                <input type="submit" value="submit" class="hideme"/>
            </form>
        </div>
        <div>
            <form action="@routes.Application.delete(id)" method="POST">
                <input type="submit" value="delete" />
            </form>
        </div>
    </li>

连同一些 jquery 在提交后向上滑动一里:

 $(document).ready(function(){
        $(".hideme").click(function(){
               $(this).closest('li.item').slideUp();
                });
            });

但是,由于表单 POST 进入必须是 return Ok(...) 或 Redirect(...) 的 Action,所以我无法让页面不重新加载或重定向。现在我的 Action 看起来像这样(无法编译):

newLinkedinForm.bindFromRequest.fold(
errors => {
  Ok("didnt work" +errors)
},
linkedin => {
  addLinkedin(linkedin.id, linkedin.url, linkedin.email, linkedin.emailsecondary, linkedin.name)
    if (checkURL(linkedin.url)) {
      linkedinParse ! Linkedin(linkedin.id, linkedin.url, linkedin.email, linkedin.emailsecondary, linkedin.name)
      Ok(views.html.index)
    }else{
     Ok(views.html.index)
    }
  }
)

是否可以 return Ok(...) 而无需重定向或重新加载?如果不是,您将如何在停留在同一页面上的同时填写表单 POST?

编辑:到目前为止,这是我使用 jquery 处理表单提交的尝试:

 $(document).ready(function(){
        $(".linkedinForm").submit(function( event ) {
            var formData = {
                'id'                : $('input[name=id]').val(),
                'name'              : $('input[name=name]').val(),
                'email'             : $('input[name=email']).val(),
                'emailsecondary'    : $('input[name=emailsecondary]').val(),
                'url'               : $('input[name=url]').val()
            };

            jsRoutes.controllers.Application.createLinkedin.ajax({
                type     :'POST',
                data     : formData

            })

            .done(function(data) { 

                console.log(data);

            });

            .fail(function(data) {

                console.log(data);
            });

            event.preventDefault();
            };
        });

这是浏览器在表单提交时的行为问题,而不是 Play 的任何行为。您可以通过在用户单击提交时更改表单的行为来绕过它。

您首先要将侦听器附加到表单的提交。你可以use jQuery for this。然后,在该处理程序中,自己 post 数据并在事件上调用 .preventDefault()。由于您的 javascript 现在负责 POST,您可以自己处理数据并更新页面的 HTML 而不是重新加载页面。

您需要的是使用 ajax 提交表单,检查:Submitting HTML form using Jquery AJAX

在您的情况下,您可以通过 var form = $(this) 获取表单对象,然后通过 form.serialize()[=12= 使用表单中的数据启动 ajax ]

    $.ajax({
        type: form.attr('method'),
        url: form.attr('action'),
        data: form.serialize(),
        success: function (data) {
            alert('ok');
        }
    });

为了完成这个任务,我不得不使用 play 的 javascriptRouting

This question's answer帮了大忙。

我没有使用 jquery 的经验,因此很难正确编写。对于那些找到这个的人,这是我最后的 jquery 有效:

 $(document).ready(function(){
        $("div#results").on("click", ".hideme", function(event) {
         var $form = $(this).closest("form");
               var id = $form.find("input[name='id']").val();
               var name = $form.find("input[name='name']").val();
               var email = $form.find("input[name='email']").val();
               var emailsecondary = $form.find("input[name='emailsecondary']").val();
               var url = $form.find("input[name='url']").val();


            $.ajax(jsRoutes.controllers.Application.createLinkedin(id, name, email, emailsecondary, url))
            .done(function(data) {
                console.log(data);
                $form.closest('li.item').slideUp()
            })
            .fail(function(data) {
                console.log(data);
            });

            });

        });

请注意,我的提交按钮是 class="hideme",从数据库中填充结果的 div 是 div#results 并且包含表格在 li 中是 class="item"。所以这个 jquery 正在做的是将一个侦听器附加到始终存在的静态 div:

<div id="results">

它等待 class="hideme" 的元素被点击。单击它时,它会从最近的表单元素中获取数据,然后通过 ajax 将该数据发送到我的控制器。如果发送成功,它将采用该形式,寻找最近的 li 并执行 .slideUp()

希望对您有所帮助