ここで私には理解できない振る舞いがあります。Spring 3.1、Primefaces 3.3.1、および JSF 2 を使用しています。
データテーブルを使用しており、フォーム内のダイアログを介して行を追加したいと考えています。これは、ダイアログを呼び出すボタンを含む私のテーブルです。
<h:form id="form">
<!-- open the dialog on click -->
<p:commandButton value="New" onclick="dlgAddTask.show()"
update="taskList" />
<p:dataTable var="task" value="#{taskBean.tasks}" id="taskList"
widgetVar="taskList" editable="true" rowkey="task.id"
paginator="true" rows="50"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="25,50,100">
<p:ajax event="rowEdit" update="@this" listener="#{taskBean.save}" />
<p:column headerText="Name" style="width:125px">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{task.name}" style="width:100%" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{task.name}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:20px">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
これは、関連する JavaScript を使用した私のダイアログです (表と同じ形式です)。
<p:dialog id="dlgAddTask" header="Add New Task" widgetVar="dlgAddTask">
<h:form>
<h:panelGrid columns="2" cellpadding="5" width="500">
<h:outputLabel for="name" value="Name" />
<p:inputText value="#{addTaskBean.name}" id="name" required="true"
label="name" />
<h:outputLabel for="description" value="Description:" />
<p:inputTextarea value="#{addTaskBean.description}"
id="description" label="description" />
<h:outputLabel for="dueTo" value="Due To:" />
<p:calendar value="#{addTaskBean.dueTo}" id="dueTo" label="dueTo" />
<h:outputLabel for="done" value="Done:" />
<p:selectBooleanCheckbox value="#{addTaskBean.done}" id="done"
label="done" />
<f:facet name="footer">
<p:commandButton id="addButton" value="Add"
actionListener="#{addTaskBean.addTask}"
oncomplete="handleLoginRequest(xhr, status, args)" />
<p:commandButton value="Cancel" onclick="dlgAddButton.hide()" />
</f:facet>
</h:panelGrid>
</h:form>
</p:dialog>
<script type="text/javascript">
function handleLoginRequest(xhr, status, args) {
if (args.validationFailed || !args.taskAdded) {
jQuery('#dialog').effect("shake", {
times : 3
}, 100);
} else {
dlgAddTask.hide();
}
}
</script>
</h:form>
そして、これが私の Bean です (ゲッターとセッターを省略しています):
public class AddTaskBean {
@Inject
TaskDao taskDao;
private boolean done;
private String name;
private String description;
private Date dueTo;
@Transactional
public void addTask() {
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage msg = null;
Task task = new Task();
boolean taskAdded = false;
task.setDescription(getDescription());
task.setDone(isDone());
task.setDueTo(getDueTo());
task.setName(getName());
if (taskDao.persist(task) != null) {
taskAdded = true;
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Task",
getName() + " added.");
} else {
taskAdded = false;
msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Task Error",
"Something went wrong on adding task.");
}
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("taskAdded", taskAdded);
}
ここで、ダイアログを開いてタスクを追加すると、更新ポイントまで機能します。データベースに新しいタスクがあり、ダイアログは閉じますが、テーブルは更新されません。F5 キーを押すと、テーブルに新しいタスクが表示されます。
しかし(説明が少し難しいので注意深く読んでください)、タスクを追加した後にダイアログを閉じないと(oncomplete="handleLoginRequest(xhr, status, args)" を介して javascript を呼び出さないことにより)、タスクも追加されますが、もちろんダイアログは開いたままです。次にキャンセルを押すと、ダイアログが閉じてテーブルが更新され、新しいタスクが表示されます。
私はこれを説明することはできません。
前もって感謝します