在PrimeFaces中使用Ajax事件时重置Bean
我有一个对话框,其中包含复选框和一个输入字段。当这个复选框被选中时,输入应该被禁用。复选框值存储在Bean中,输入值是所选对象值之一。在PrimeFaces中使用Ajax事件时重置Bean
当用户点击列表上的链接时,弹出此对话框。 Dialog的输入正在使用模型中的值填充。
我也有两个按钮:保存和取消。在保存时,根据复选框的值,我对模型做了不同的事情并更新它。在取消我想什么都不做。
问题是:当有Ajax事件与复选框连接时,Bean中的值会自动更新。因此,点击取消并重新打开对话框后,我得到了最后一个状态,但我想要初始状态。
下面是代码:
列表
<h:form id="termPanelForm"> <p:dataTable id="termPanelTable"
value="#{termRightPanelController.terms}" var="term" emptyMessage="">
<p:column>
<p:commandLink value="#{term.subject}"
action="#{termRightPanelController.setTerm(term)}"
oncomplete="termRealizeDlg.show();"
update=":termRealizeForm:termRealizeDialog" />
</p:column>
<p:column width="50">
<h:outputText value="#{term.dateRealization}">
<f:convertDateTime pattern="dd-MM-yy HH:mm" />
</h:outputText>
</p:column>
</p:dataTable>
</h:form>
对话框
<h:form id="termRealizeForm"> <p:dialog id="termRealizeDialog" widgetVar="termRealizeDlg"
modal="true" resizable="false" closeOnEscape="true"
header="#{termRightPanelController.selectedTerm.subject}">
<p:messages autoUpdate="true" showDetail="true"></p:messages>
<p:panelGrid columns="2" styleClass="border-none">
<p:outputLabel for="realized" value="#{i18n['Term.MarkRealized']}" />
<p:selectBooleanCheckbox id="realized"
value="#{termRightPanelController.termRealized}">
<p:ajax process="@this" update="dateRealization" />
</p:selectBooleanCheckbox>
<p:outputLabel for="dateRealization"
value="#{i18n['Term.ChangeDateRealization']}" />
<p:inputText id="dateRealization"
value="#{termRightPanelController.selectedTerm.dateRealization}"
pattern="dd-MM-yyyy HH:mm"
disabled="#{termRightPanelController.termRealized}" >
</p:inputText>
</p:panelGrid>
<h:panelGroup layout="block" styleClass="buttons-group">
<p:commandButton value="#{i18n['Common.Save']}"
oncomplete="hideDialogWhenValid(termRealizeDlg, xhr, status, args);"
action="#{termRightPanelController.editTerm()}"
update=":termPanelForm:termPanelTable" icon="ui-icon-check"></p:commandButton>
<p:commandButton onclick="termRealizeDlg.hide();"
value="#{i18n['Common.cancel']}"
icon="ui-icon-cancel" update=":termRealizeForm:termRealizeDialog">
</p:commandButton>
</h:panelGroup>
</p:dialog>
</h:form>
豆
@SuppressWarnings("rawtypes") @ManagedBean
@ViewScoped
public class TermRightPanelController extends MainController implements Serializable {
private static final long serialVersionUID = 6283828584670862366L;
private TermServiceLocal termService = ServiceLocator.locateService(
TermService.class, TermServiceLocal.class);
private List<Term> terms;
private Term selectedTerm;
private boolean termRealized;
@PostConstruct
public void init() {
loadTerms();
}
public void loadTerms() {
terms = termService.getTermsNotRealized(getLoggedUser().getId());
}
public String expiredTerm(Term term) {
long time = new Date().getTime();
if (term.getDateRealization().getTime() > time) {
return "";
}
return "expired";
}
public void editTerm() {
if (termRealized) {
selectedTerm.setDateRead(new Date());
} else {
selectedTerm.setDateRead(null);
}
termService.merge(selectedTerm);
loadTerms();
}
public void setTerm(Term term) {
this.selectedTerm = term;
}
public List<Term> getTerms() {
return terms;
}
public void setTerms(List<Term> terms) {
this.terms = terms;
}
public Term getSelectedTerm() {
return selectedTerm;
}
public void setSelectedTerm(Term selectedTerm) {
this.selectedTerm = selectedTerm;
}
public boolean isTermRealized() {
return termRealized;
}
public void setTermRealized(boolean termRealized) {
this.termRealized = termRealized;
}
@Override
public Class getModelClass() {
return this.getClass();
}
}
在这种特殊情况下,当我单击取消时,总是可以将termRealized
设置为false,但在其他场景中,我已从模型中加载值。所以重新打开对话框后,我想要有与模型中相同的值,而不是由Bean存储。
我们已经讨论了球队的一些可能的解决方案,但对我们来说,似乎都讨厌:
- 我们可以在特定克隆
selectedTerm
和克隆重新加载它取消。这是令人讨厌的,因为我们需要在我们想要编辑的每个元素上实现可克隆的接口。 - 我们可以编写自定义JavaScript来处理禁用的事件和其他事件。但是我们想避免使用JS,因为这不是干净的解决方案。
- 我们可以从取消型号上重新加载
selectedTerm
,然后将其替换为terms
列表。但是,为什么我们不得不再次从DB获取一些东西? - 我们可以重新加载整个
terms
列表。这比第三种解决方案更糟糕。
我们也尝试了内置的重置选项(resetInput标记和其他),但没有用。有没有优雅的方法来解决这个问题,或者我们的建议是正确的?
回答:
我会用下面的方法做。
创建的期限一copy constructor:
public class Term { private String dummy;
public Term() {
}
//copy constructor
public Term(Term another) {
this.dummy = another.dummy; // and set the rest of the values
}
}
和内部DataTable中的按钮调用选择方法。
<p:commandLink value="#{term.subject}" action="#{termRightPanelController.selectTerm(term)}"
oncomplete="termRealizeDlg.show();"
update=":termRealizeForm:termRealizeDialog" />
selectTerm(期限项)
public void selectTerm(Term term) { selectedTerm = new Term(term);
}
对话框onHide
<p:dialog id="termRealizeDialog" widgetVar="termRealizeDlg" modal="true" resizable="false" closeOnEscape="true"
header="#{termRightPanelController.selectedTerm.subject}"
onHide="restDialog()">
restDialog() remoteCommand
<p:remoteCommand name="restDialog" actionListener="#{termRightPanelController.restDialogValues()}" />
个 restDialogValues()
public void restDialogValues() { setTermRealized(false);
}
保存按钮
<p:commandButton value="#{i18n['Common.Save']}" action="#{termRightPanelController.editTerm()}" />
editTerm()
public void editTerm() { ....
terms.remove(selectedTerm);//assuming equals and hashcode works on ID
terms.add(selectedTerm);
// Or loop over the terms and find your selectedTerm by id
// if the equals and hashcode are not implemented on the ID,
//then remove it and add the new one
....
}
希望这有助于。
以上是 在PrimeFaces中使用Ajax事件时重置Bean 的全部内容, 来源链接: utcz.com/qa/263943.html