我正在構建一些粗略的CMS類功能(以獲得Play Framework的認可)。對於這個測試用例,我構建了2個頁面,1個用於列出標籤,1個用於創建/編輯/保存標籤。玩框架:如何使用datamodel在驗證失敗時重新填充表單?
的流動是這樣的(路由文件):
#list tags
GET /tags Application.listTags
#view/edit existing tag
GET /tag/{<(?!new$)(.+)>name} Application.showTag
#new tag
GET /tag/new Application.showTag
創建/查看/編輯頁面顯示形式得到它的從tagDTO值。 正常流程沒有問題,但當表單提供驗證錯誤(例如:標記名稱必須存在)時,我想再次顯示該頁面,用編輯後的值重新填充表單。我可以使用包含這些最後值的'flash'對象,但是表單已經綁定到tagDTO(在重定向時爲空),而不是'flash' -目的。
首先代碼: 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
#{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}
現在我能想到的一些方法,使其工作,但沒有真正的優雅:
將表單綁定到flash對象(或params對象)並填充flas/params - 對象來自標記DTO
在驗證失敗時,重新獲取tagDTO(不再有效,因此DB調用是必需的),並使用Flash對象中可用的值覆蓋tagDTO中的值,將表單綁定到tagDTO。
2一樣,但使用某種緩存快速獲取tagDTO(所以不需要DB-調用)
一些通用的機制從/列席會議,(反)序列tagDTO。
總之,我不喜歡他們中的任何一個。 在這種情況下,您認爲什麼是最佳實踐?或者,我缺少Play框架中的任何功能?
很高興知道顯式的render-call構造(使用另一個動作的模板)。我改變了一下你的建議,通過重新制作我的tagDTO和suppyling,e。 g:render(「@ showTag」,tagDTO); –
也很好知道(並且當你想到它時非常合乎邏輯)你不需要params.flash();和/或validation.keep();在做渲染之前(「@ showTag」,tagDTO); (如果你這樣做,你會被上一篇文章中的錯誤搞砸)。再次感謝 –