播放框架:使用数据模型时,如何在验证失败时重新填充表格? [英] play framework: how to repopulate form on validation-failure when using datamodel?

查看:91
本文介绍了播放框架:使用数据模型时,如何在验证失败时重新填充表格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一些类似CMS的粗略功能(以与Play Framework融为一体).对于此测试用例,我构建了2页,其中1页用于列出标签,而1页用于创建/编辑/保存标签.

I'm building some crude CMS-like functionality (to get acquinted with Play Framework). For this test-case I've build 2 pages, 1 for listing tags and 1 for creating/editing/saving tags.

流是这样的(路由文件):

The flow is like this (routes-file):

#list tags
GET /tags  Application.listTags 

#view/edit existing tag
GET /tag/{<(?!new$)(.+)>name} Application.showTag  

#new tag
GET /tag/new  Application.showTag   

创建/查看/编辑页面显示一个表单,该表单从tagDTO获取其值. 正常流程没有问题,但是当表单出现验证错误(例如,标记名必须存在)时,我想再次显示页面,并使用编辑后的值重新填充表单.

the create/view/edit page displays a form which gets it's values from a tagDTO. The normal flow works without problems, but when the form gives validation-errors (e.g: the tag-name must exist) I want to display the page again, repopulating the form with the edited values.

为此(遵循Play Framework约定),我可以使用包含这些最后值的'flash'对象,但是该格式已绑定到tagDTO(重定向时为null),而不是'flash'-目的.

For this (following the Play Framework conventions) I could use the 'flash'-object which contains these last values, but the form is already bound to the tagDTO (which is null on redirect) instead of the 'flash'-object.

首先输入代码: Application.java

First the code: Application.java

.....

public static void showTag(String name) {
    TagDTO tagDTO = TagDTO.buildDTOFromModelOrNew(name);
    render(tagDTO); 
}


/**
 * Save tag and redirect to Show
 * 
 * @param name
 * @param displayname
 * @param isnew
 */
public static void saveTag(
        @Required(message="Name is required") String name,
        String displayname,
        boolean isnew) 
{
    checkAuthenticity();
    if(validation.hasErrors()) {
        params.flash(); 
        validation.keep(); 
        showTag(null);
    }

    //fetch tagDTO based on backend or create new if not exist
    TagDTO tag = TagDTO.buildDTOFromModelOrNew(name);

    // Append / Overwrite values
    tag.displayname = displayname;
    tag.name = name;

    //save result to model
    TagDTO.buildAndSaveModelFromDTO(tag);

    flash.success("Thanks for " + (isnew?"creating":"updating") + " tag " + tag.name);

    //redirect to show
    showTag(tag.name);
} 

和ShowTag.html

And 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}

现在我可以想到一些使其工作的方法,但是没有一种非常优雅的方法:

Now I could think of some ways to make it work, but none really elegant:

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

  1. bind the form to the flash-object (or params-object) and populate the flas/params- object from the tagDTO

,在验证失败时,重新获取tagDTO(不再可用,因此需要进行DB调用),并用flash-object中可用的值覆盖tagDTO中的值,并将表单绑定到tagDTO.

on validation-failure, refetch the tagDTO (not avail anymore so DB-call necessary) and overwrite values in tagDTO with values available in flash-object, bind form to tagDTO.

类似于2,但是使用某种缓存来快速获取tagDTO(因此无需进行数据库调用)

like 2, but using some sort of cache to quickly fetch tagDTO (so no need for db-call)

一些通用机制,用于在会话之间对tagDTO进行反序列化.

Some general mechanism to (de)serialize tagDTO from/to the session.

简而言之,我真的不喜欢他们中的任何一个. 在这种情况下,您认为什么是最佳做法?还是我缺少的Play框架中的任何功能?

In short, I don't like any of them really. What would you consider to be a best practice in this situation? Or is there any functionality in the Play Framework that I'm missing?

推荐答案

在这里,显式渲染调用非常方便.保留先前提交的表单值,然后将其返回(如果验证失败),如下所示,

This is where the explicit render calls comes handy. Retain the form values from previous submission and give it back (if validation fails) as follows,

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

这将避免您调用来自另一个动作的动作"时发生的额外重定向(在Play情况下为307).

This will avoid the extra redirect (307 in case of Play!) that would have happened if you had called 'action from another action'.

这篇关于播放框架:使用数据模型时,如何在验证失败时重新填充表格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆