lin*_*ips 5 playframework playframework-2.0
我正在使用Play框架,我有一个常见的用例,用控制器动作中的表单更新模型.但是我有一些问题需要理解它背后的概念,因为如果你有一个包含模型所有属性的表单,那么这个问题就可以了.如果您只有一个部分表单,例如只编辑用户模型的密码,则此方法会破坏模型,因为它会将模型的其他属性设置为null.这个问题有"官方"解决方案吗?任何方式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());
}
}
Run Code Online (Sandbox Code Playgroud)
可能该解决方案在某种程度上可以使用其他参数调用bindFormRequest()方法,如字符串或字符串映射?但我无法找到目的.对此的一些见解也会很棒.非常感谢!
在最近的一个项目中,我需要这种功能,我不得不重新实现Form类(基于原始的Play表单)以允许该bindFromRequest()方法的附加参数.
以您的代码为例,它会变成这样:
Model model = Model.findById(id);
Form<Model> filledForm = CustomForm.form(Model.class).bindFromRequest(model);
Run Code Online (Sandbox Code Playgroud)
我们的想法是只修改表单中定义的字段,并保持模型的其他字段不被修改.
要允许此特定绑定,您必须使用以下内容重新定义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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
而不是创建的DataBinder与blankInstance()作为标准的播放Form类呢,你跟你创建模型实例作为构造函数的参数.
| 归档时间: |
|
| 查看次数: |
2144 次 |
| 最近记录: |