5

我正在使用 Play 框架,并且我有一个常见的用例来更新具有控制器操作中的表单的模型。但是我在理解它背后的概念时遇到了一些问题,因为如果你有一个包含模型所有属性的表单,这只是工作。如果您只有部分表单,例如只编辑用户模型的密码,则此方法会破坏模型,因为它将模型的其他属性设置为空。这个问题有什么“官方”解决方案吗?Play 以任何方式仅更新现有属性吗?

public static Result update(Long id) {
    Model model = Model.findById(id);
    Form<Model> filledForm = modelForm.bindFromRequest();
    if (filledForm.hasErrors()) {
        return badRequest(edit.render(filledForm));
    } else {
        model.update();
        flash("message", "Created new Model!");
        return ok(index.render());
    }
}

可能解决方案以某种方式在于可以使用附加参数调用 bindFormRequest() 方法,例如字符串或字符串映射?但我无法找出这样做的目的。对此的一些见解也会很棒。非常感谢!

4

3 回答 3

7

在最近的一个项目中,我需要这种功能,并且我必须重新实现 Form 类(基于原始 Play Form)以允许该bindFromRequest()方法的附加参数。

以你的代码为例,它会变成这样:

Model model = Model.findById(id);
Form<Model> filledForm = CustomForm.form(Model.class).bindFromRequest(model);

这个想法是只修改表单中定义的字段,并保持模型的其他字段不变。

要允许此特定绑定,您必须使用以下内容重新定义bind(Map<String,String> data, String... allowedFields)方法(以及bindFromRequest):

public Form<T> bind(T instance, Map<String,String> data, String... allowedFields) {

    DataBinder dataBinder = null;
    Map<String, String> objectData = data;
    if(rootName == null) {
        dataBinder = new DataBinder(instance);
    } else {
        dataBinder = new DataBinder(instance, rootName);
        objectData = new HashMap<String,String>();
        for(String key: data.keySet()) {
            if(key.startsWith(rootName + ".")) {
                objectData.put(key.substring(rootName.length() + 1), data.get(key));
            }
        }
    }

不是像标准 Play Form 类那样创建 with ,而是使用模型实例作为构造函数参数来创建它DataBinderblankInstance()

于 2013-06-21T08:44:58.593 回答
1

有一个解决方案。我要做的是制作一个更加面向服务的应用程序。您为特定操作创建表单和模型的位置:updateUserPasswordupdateUserEmail等,并在您的模型中实现这些简单的方法。

于 2013-06-21T06:50:23.713 回答
0

我建议您看一下 scala 方向,因为您可以将 scala 和 java 合并到一个项目中,使用 scala 您的表单可能是tuple例如:

val someForm = Form(tuple("user_id" -> number, "password"->text))然后根据您的请求,您可以使用它来执行模型更新:

someForm.bindFromRequest.fold(
formWithErrors => {
BadRequest
},

data => {
// update method takes two parameters user_id and password to update
User.updatePassword(data._1,data._2)
Ok("...")
}
)
于 2013-06-21T10:18:34.813 回答