Model view controller play framework:使用datamodel时,如何在验证失败时重新填充表单?

Model view controller play framework:使用datamodel时,如何在验证失败时重新填充表单?,model-view-controller,playframework,Model View Controller,Playframework,我正在构建一些粗糙的类似CMS的功能(以获得Play框架的认可)。对于这个测试用例,我构建了2个页面,1个用于列出标记,1个用于创建/编辑/保存标记 流程如下所示(路由文件): 和ShowTag.html #{extends 'main.html' /} #{if flash.success} <p class="success">${flash.success}</p> #{/if} #{ifErrors}

我正在构建一些粗糙的类似CMS的功能(以获得Play框架的认可)。对于这个测试用例,我构建了2个页面,1个用于列出标记,1个用于创建/编辑/保存标记

流程如下所示(路由文件):

和ShowTag.html

    #{extends 'main.html' /}
    #{if flash.success}
        <p class="success">${flash.success}</p>
    #{/if}

    #{ifErrors}
        <p class="errors">Oops...</p>
    #{/ifErrors}

    #{form @Application.saveTag()}
        #{authenticityToken /}
        <p>
            <label for="name">Name: </label>
            <input type="text" name="name" id="name" value="${tagDTO.name}" />
            <span class="error">#{error 'name' /}</span>
        </p>
        <p>
            <label for="displayname">Displayname: </label>
            <input type="text" name="displayname" id="displayname" value="${tagDTO.displayname}" />
            <span class="error">#{error 'displayname' /}</span> 
        </p>
        <p>
            <input type="hidden" name="isnew" value="${tagDTO.isnew}" />
            <input type="submit" value="Submit your comment" />
        </p>
    #{/form}
#{扩展'main.html'/}
#{if flash.success}

${flash.success}

#{/if} #{iferros}

哎呀

#{/iferros} #{form@Application.saveTag()} #{authenticityToken/} 姓名: #{错误'name'/}

显示名称: #{错误'displayname'/}

#{/form}
现在我可以想出一些办法让它发挥作用,但没有一个真正优雅:

  • 将表单绑定到flash对象(或params对象),并从tagDTO填充flas/params-object

  • 验证失败时,重新蚀刻tagDTO(不再有效,因此需要DB调用),并使用flash对象中可用的值覆盖tagDTO中的值,将表单绑定到tagDTO

  • 类似于2,但使用某种缓存来快速获取tagDTO(因此不需要db调用)

  • 将tagDTO从会话(反)序列化到会话的一些通用机制

  • 总之,我真的不喜欢他们中的任何一个。
    在这种情况下,你认为最好的做法是什么?或者在Play框架中是否有我缺少的功能

    这就是显式渲染调用方便的地方。保留上一次提交的表单值,并按如下方式返回(如果验证失败)

    checkAuthenticity();
    if(validation.hasErrors()) {
        render("@showTag", name, displayname, isnew);
    }
    

    这将避免额外的重定向(在游戏中为307!),如果您调用了“来自另一个操作的操作”,则会发生这种情况。

    再次呈现表单,并避免重定向是一种解决方案。我认为如果用户按F5键,他会再次出现错误。但是我认为您应该创建一个重载/取消按钮,这样用户就可以忽略所有信息

    要始终使用正确的URL,可以在routes.conf中执行以下操作:

    GET  /tag/create     TagController.create
    POST /tag/create     TagController.insert
    

    flash解决方案的缺点是cookie可能变得非常大。

    了解显式渲染调用构造(使用另一个操作的模板)很好。我改变了你的建议,把我的标签重新贴上,并补充说,e。g:渲染(“@showTag”,tagDTO);知道不需要params.flash()也是很好的(考虑到这一点,这也是很合乎逻辑的);和/或验证。保留();在进行渲染之前(“@showTag”,tagDTO);(如果你这样做了,你就会被上一篇文章中的错误搞得一团糟)。再次感谢有人在scala中找到了一个现代解决方案?谢谢,事实上我已经将routes文件更改为类似的内容。可以肯定的是,您实际上在推广与“sjn”在上面所做的相同的解决方案?(因此渲染时不重定向,也不使用flash对象)?
    checkAuthenticity();
    if(validation.hasErrors()) {
        render("@showTag", name, displayname, isnew);
    }
    
    GET  /tag/create     TagController.create
    POST /tag/create     TagController.insert