单元格editMode中的JSF Primefaces数据表未将编辑后的值发送到托管bean [英] JSF Primefaces datatable in cell editMode not sending the edited value to the managed bean
问题描述
我有两个素数表dataTables.第一个显示MainEntity的实例.第二个显示在第一个数据表上与所选MainEntity关联的单词(仅字符串)列表.
I have two primefaces dataTables. The first show the instances of a MainEntity. The second one show a list of Words (just strings) associated with the selected MainEntity on the first datatable.
打印屏幕说明了我的意思.
The printscreen illustrates what I mean.
我的问题是,当我在单词列表"上编辑字符串时,我的侦听器方法将不会收到新值.实际上,当我调用 event.getNewValue()
方法时,我得到的是旧值.
My problem is, when I edit a string on the Word List, my listener method won't receive the new value. In fact, when I call the event.getNewValue()
method, I get old value.
我想念什么?
我正在使用JavaServer Faces 2.2,Primefaces 5.0和Spring Framework 4.0.3.
I'm using JavaServer Faces 2.2, Primefaces 5.0 and Spring Framework 4.0.3.
在此先感谢您的帮助.
xhtml,托管bean和MainEntity的代码如下:
The code for the xhtml, the managed bean and the MainEntity are as follows:
mainEntity.xhtml:
mainEntity.xhtml:
<h:body>
<h:form id="mainEntityForm">
<p:panelGrid columns="1" fullPage="true" id="dashboard">
<f:facet name="header">
<h2>MainEntity Table</h2>
</f:facet>
<p:panel>
<f:facet name="header">
MainEntity List
<p:commandButton value="New MainEntity"
actionListener="#{mainEntityController.createMainEntityDialog}"
styleClass="header-button">
<p:ajax event="dialogReturn" update=":mainEntityForm:mainEntityTable" />
</p:commandButton>
</f:facet>
<p:dataTable id="mainEntityTable" var="mainEntity" value="#{mainEntityController.mainEntities}"
editable="true" editMode="cell" widgetVar="cellMainEntity"
selectionMode="single" selection="#{mainEntityController.selectedMainEntity}"
rowKey="#{mainEntity.id}" tableStyle="width:auto">
<p:ajax event="rowSelect" update=":mainEntityForm:stringGrid :mainEntityForm:entityAGrid :mainEntityForm:entityBGrid" />
<p:ajax event="cellEdit" listener="#{mainEntityController.onEditMainEntity}" update=":mainEntityForm:mainEntityTable" />
<p:column headerText="ID">
<h:outputText value="#{mainEntity.id}" />
</p:column>
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText id="nameOutput" value="#{mainEntity.name}" />
</f:facet>
<f:facet name="input">
<h:inputText id="atyInput" value="#{mainEntity.qty}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Commands">
<p:commandButton title="Remove MainEntity" icon="ui-icon-trash"
actionListener="#{mainEntityController.deleteMainEntity(mainEntity)}"
update=":mainEntityForm:mainEntityTable" />
</p:column>
</p:dataTable>
</p:panel>
<p:panelGrid fullPage="true" id="mainEntityDetail">
<f:facet name="header">
<p:row>
<p:column colspan="4">
<h2>MainEntity Detail</h2>
</p:column>
</p:row>
</f:facet>
<p:row>
<p:column>
<p:panel>
<f:facet name="header">
Word List
<p:commandButton value="New Word"
actionListener="#{mainEntityController.addNewWord()}"
styleClass="header-button"
update=":mainEntityForm:wordGrid">
</p:commandButton>
</f:facet>
<p:dataTable id="wordGrid" var="word"
value="#{mainEntityController.selectedMainEntity.wordList}"
tableStyle="width:auto" editable="true" editMode="cell" widgetVar="cellWord">
<p:ajax event="cellEdit" listener="#{mainEntityController.onEditWord}" />
<p:column headerText="Word">
<p:cellEditor>
<f:facet name="output">
<h:outputText id="wordOutput" value="#{word}" />
</f:facet>
<f:facet name="input">
<h:inputText id="wordInput" value="#{word}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Commands">
<p:commandButton title="Remove Word"
icon="ui-icon-trash"
actionListener="#{mainEntityController.removeWord(word)}"
update=":mainEntityForm:wordGrid" />
</p:column>
</p:dataTable>
</p:panel>
</p:column>
</p:row>
</p:panelGrid>
</p:panelGrid>
</h:form>
</h:body>
MainEntityController.java(托管bean):
MainEntityController.java (managed bean):
@ManagedBean
@SessionScoped
public class MainEntityController {
//...
private MainEntity selectedMainEntity;
public List<MainEntity> mainEntities;
//...
public MainEntity getSelectedMainEntity(){
return selectedMainEntity;
}
public void setSelectedMainEntity(MainEntity mainEntity){
this.selectedMainEntity = mainEntity;
}
//...
public void onEditWord(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
// THE PROBLEM IS HERE
// I NEVER ACTUALLY REACH THIS CODE
// newValue is always equal to oldValue!
FacesContext context = FacesContext.getCurrentInstance();
String word = context.getApplication().evaluateExpressionGet(context, "#{word}", String.class);
System.out.println(newValue);
System.out.println(word);
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Word Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
}
MainEntity.java:
MainEntity.java:
@Entity
public class MainEntity {
@Id
private String id;
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(
name="MainEntity_Word",
joinColumns = @JoinColumn(name = "id", referencedColumnName="id")
)
@Column(name = "word")
private Set<String> wordList;
//...
public void addWord(String word) {
this.wordList.add(word);
}
public void removeWord(String word) {
this.wordList.remove(word);
}
public Set<String> getWordList() {
return wordList;
}
public void setWordList(Set<String> wordList) {
this.wordList = wordList;
}
}
推荐答案
我终于开始使用它了.
我怀疑String是不可变的,我所做的就是将'word'封装在如下所示的类中:
I suspected of the String immutable nature and what I did was to encapsulate the 'word' in a class like the following:
public class Word {
private String word;
Word (String word) {
this.setWord(word);
}
public String getWord() {
return this.word;
}
public void setWord(String word) {
this.word = word;
}
}
在那之后,我还必须在托管bean(控制器)中创建一个集合来保存一组单词,例如"private setmanagedWordList;".
After that, I also had to create a set inside the managed bean (controller) to hold the set of words, like 'private Set managedWordList;'.
我还更改了托管bean内列表的getter,以将String设置转换为Word设置,例如:
I also changed the getter for the list, inside the managed bean, to convert from the String set to a Word set like:
public Set<Word> getWordList() {
if (this.selectedMainEntity != null){
this.wordList = new HashSet<Word>();
for (String word : this.selectedMainEntity.getWordList()) {
this.wordList.add(new Word(word));
}
}
return this.wordList;
}
最后,我更改了dataTable以引用新集合.发件人:
Finally, I changed the dataTable to reference the new set. From:
<p:dataTable ... value="#{mainEntityController.selectedMainEntity.wordList}"... />
收件人:
<p:dataTable ... value="#{mainEntityController.wordList}"... />
只有到那时,我才能按预期工作.
And only then I got it to work as I expected.
这篇关于单元格editMode中的JSF Primefaces数据表未将编辑后的值发送到托管bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!