JSF-как получить старое и новое значение при использовании Primefaces RowEditEvent?
у меня есть datatable с 2 столбцами (имя и описание), и я хочу обновить свою базу данных, когда человек обновляет строку и нажимает галочку, которая запускает execBacking.update
метод.
в этом методе я получаю новые значения, бросая event.getObject()
, но как я могу также получить старые значения? Имя-мой первичный ключ, поэтому мне нужно старое значение, чтобы знать, какую строку обновлять в БД.
страница xhtml
<p:ajax event="rowEdit" listener="#{execBacking.update}" update=":execForm:execMessages" />
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{exec.name}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{exec.name}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Description">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{exec.description}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{exec.description}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Actions">
<p:rowEditor />
<p:commandLink styleClass="ui-icon ui-icon-trash" type="submit" actionListener="#{execBacking.delete}" update=":execForm:execMessages" >
<f:attribute name="execName" value="#{exec.name}" />
</p:commandLink>
</p:column>
</p:dataTable>
поддержка bean
public void update(RowEditEvent event) {
Dao dao = new Dao(ds);
Exec exec = (Exec) event.getObject();
System.out.println("name = "+exec.getName()); //New name
System.out.println("desc = "+exec.getDescription()); //New desc
try {
// If the new exec was updated successfully
if(dao.updateExec(accessBacking.getUsername(), null, exec.getName(), exec.getDescription())) {
FacesContext.getCurrentInstance().addMessage("growl", new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "Exec Updated Successfully!"));
} else {
FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Error Updating Exec!"));
}
} catch (Exception e) {
FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", e.getMessage()));
}
}
2 ответов
Я бы порекомендовал не С name
будьте вашим первичным ключом, но вместо этого добавьте автоматическое увеличение id
поле и сделайте это своим первичным ключом, и не сделать это поле редактируемым пользователем. Это гарантирует, что у вас всегда есть доступ к записи, которую вы хотите обновить.
вообще говоря это плохая практика, чтобы попытаться изменить первичный ключ в базе данных, как вы пытаетесь сделать это.
вы можете зарегистрировать ValueChangeListener
на компоненте вы заинтересованы в использовании:
<p:column headerText="Description">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{exec.name}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{exec.name}">
<f:valueChangeListener binding="#{keyChangedListener}"/>
<f:ajax/>
</h:inputText>
</f:facet>
</p:cellEditor>
</p:column>
keyChangeListener
будет соответствовать реализации ValueChangeListener
и мы, используя <f:ajax/>
здесь, чтобы убедиться, что valueChanged
событие запускается в текстовом поле. В противном случае слушатель не будет уведомлен. Ваш слушатель должен выглядеть примерно так:
@ManagedBean(name="keyChangedListener")
@ViewScoped
public class KeyChangeListener implements ValueChangeListener{
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException{
Object oldValue = event.getOldValue(); //get the old value
Object newValue = event.getNewValue(); //get the new value
}
я использую @ViewScoped
здесь как посоветовано спецификацией JSF, избежать излишних побочных эффектов.