我尝试了很多事情。该线程与另一个线程相关,但是现在问题更具体了。我发现方法getRowData()
以及我实现的方法getRowKey()
都不会被调用。
我尝试过的事情:
在我的.xhtml文件中,设置rowKey很好。没有编译器错误。在控制器中,写下getRowData()
。我尝试选择某些内容,这会破坏整个页面。设置器不会被呼叫。如果我不覆盖getRowData()
,编译器仍然可以工作。
当我尝试在Controller中实现getRowKey()
和getRowData()
时,它会告诉我... exception [getRowKey(T object) must be implemented by ...
然后我尝试实现SelectableDataModel
,以查看是否有区别,但没有区别。
当我删除selectionMode
时,整个选择都很好。分页效果很好。编辑列也可以。但是删除条目所需的contextMenu不起作用。
xhtml:
<h:form id="eintraegeList">
<p:panel header="Liste aller Einträge">
<p:dataTable id="table"
var="telefonbuch"
lazy="true"
widgetVar="tableWv"
value="#{telefonbuchList.lazyModel}"
editable="true"
resizableColumns="true"
liveResize="true"
style="margin-bottom:20px"
paginator="true"
rows="#{telefonbuchList.pageSize}"
emptyMessage="Keine Telefonbucheinträge vorhanden"
selectionMode="single"
selection="#{telefonbuchList.selectedEntry}"
rowKey="#{telefonbuch.id}"
currentPageReportTemplate="{startRecord}-{endRecord} von {totalRecords}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,8,10">
<f:facet name="header">
<p:commandButton id="toggler" type="button" value="Anzeige" style="float:right" icon="pi pi-align-justify" />
<p:columnToggler datasource="table" trigger="toggler" />
</f:facet>
<p:ajax event="rowEdit" listener="#{telefonbuchList.onRowEdit}" update="table" />
<p:ajax event="rowEditCancel" listener="#{telefonbuchList.onRowCancel}" update="table" />
<p:ajax event="cellEdit" listener="#{telefonbuchList.onCellEdit}" update="table" />
<p:ajax event="rowSelect" listener="#{telefonbuchList.onRowSelect}" update="table" />
<p:separator />
<p:column headerText="ID" sortBy="#{telefonbuch.id}">
<h:outputText value="#{telefonbuch.id}" />
</p:column>
<p:column headerText="Vorname" sortBy="#{telefonbuch.vorname}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.vorname}" /></f:facet>
<f:facet name="input"><p:inputText id="vornameInput" value="#{telefonbuch.vorname}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Nachname" sortBy="#{telefonbuch.nachname}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.nachname}" /></f:facet>
<f:facet name="input"><p:inputText id="nachnameInput" value="#{telefonbuch.nachname}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Telefonnummer" sortBy="#{telefonbuch.telefonnummer}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.telefonnummer}" /></f:facet>
<f:facet name="input"><p:inputText id="telefonnummerInput" value="#{telefonbuch.telefonnummer}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Handynummer" sortBy="#{telefonbuch.handynummer}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.handynummer}" /></f:facet>
<f:facet name="input"><p:inputText id="handynummerInput" value="#{telefonbuch.handynummer}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Geschäftsstelle" sortBy="#{telefonbuch.geschaeftsstelle}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.geschaeftsstelle}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{telefonbuch.geschaeftsstelle}" style="width:100%">
<f:selectItems value="#{telefonbuchController.geschaeftsstellen}" var="c" itemLabel="#{geschaeftsstelle}" itemValue="#{geschaeftsstelle}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Geschlecht" sortBy="#{telefonbuch.gender.shortGender}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.gender.shortGender}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu id="gender" value="#{telefonbuch.gender}" style="width:100%">
<f:selectItem itemLabel="Keine Angabe" itemValue="" />
<f:selectItems value="#{telefonbuch.genders}" var="gender" itemLabel="#{gender.shortGender}" itemValue="#{gender}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column exportable="false" style="width:20px;text-align:center;">
<p:rowEditor />
</p:column>
</p:dataTable>
<p:growl id="growl" showDetail="true" for="eintraege-list">
<p:autoUpdate />
</p:growl>
<p:separator />
<p:contextMenu for="table">
<p:menuitem value="Löschen" update="table" icon="fas fa-eraser" action="#{telefonbuchList.deleteEntry}"/>
<p:menuitem value="Edit Cell" icon="pi pi-search" onclick="PF('tableWv').showCellEditor();return false;"/>
</p:contextMenu>
</p:panel>
</h:form>
控制器:
@Scope(value = "session")
@Component(value = "telefonbuchList")
@ELBeanName(value = "telefonbuchList")
@Join(path = "/", to = "/eintraege-liste.jsf")
public class TelefonbuchListController extends LazyDataModel<Telefonbuch> {
private static final long serialVersionUID = 1L;
@Autowired
private TelefonbuchRepository telefonbuchRepository;
private List<Telefonbuch> selectedEntries;
private Telefonbuch selectedEntry;
private LazyDataModel<Telefonbuch> lazyModel;
private int pageSize = 5;
public void deleteEntry() {
telefonbuchRepository.deleteAll(selectedEntries);
lazyModel.getWrappedData().removeAll(selectedEntries);
selectedEntries.clear();
}
public LazyDataModel<Telefonbuch> getLazyModel() {
return lazyModel;
}
@Override
public int getPageSize() {
return pageSize;
}
@Override
public Telefonbuch getRowData(String rowKey) {
System.out.println("rowKey: " + rowKey);
List<Telefonbuch> list = getWrappedData();
for (Telefonbuch telefonbuch : list) {
if (telefonbuch.getId().toString().equals(rowKey)) {
return telefonbuch;
}
}
return null;
}
@Override
public Object getRowKey(Telefonbuch telefonbuch) {
return telefonbuch != null ? telefonbuch.getId() : null;
}
public List<Telefonbuch> getSelectedEntries() {
return selectedEntries;
}
public Telefonbuch getSelectedEntry() {
return selectedEntry;
}
@Deferred
@RequestAction
@IgnorePostback
public void loadData() {
lazyModel = new LazyDataModel<Telefonbuch>() {
private static final long serialVersionUID = 1L;
@Override
public List<Telefonbuch> load(int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
List<Telefonbuch> result = new ArrayList<Telefonbuch>();
if (first == 0) {
if (sortField != null && !sortField.isEmpty()) {
if (sortOrder.name().equalsIgnoreCase("ascending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).ascending()))
.getContent();
} else if (sortOrder.name().equalsIgnoreCase("descending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).descending()))
.getContent();
}
} else {
result = telefonbuchRepository.findAll(PageRequest.of(first, pageSize)).getContent();
}
} else {
first = first / pageSize;
if (sortField != null && !sortField.isEmpty()) {
if (sortOrder.name().equalsIgnoreCase("ascending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).ascending()))
.getContent();
} else if (sortOrder.name().equalsIgnoreCase("descending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).descending()))
.getContent();
}
} else {
result = telefonbuchRepository.findAll(PageRequest.of(first, pageSize)).getContent();
}
}
return result;
}
};
lazyModel.setRowCount((int) telefonbuchRepository.count()); // Aufruf auslagern, aber bei gemeinsamen Arbeiten kann neue Row hinzukommen
lazyModel.setPageSize(pageSize);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
telefonbuchRepository.save((Telefonbuch) newValue);
}
public void onRowEdit(RowEditEvent event) {
Object oldValue = event.getObject();
telefonbuchRepository.save((Telefonbuch) oldValue);
FacesMessage msg = new FacesMessage("Eintrag geändert",
((Telefonbuch) event.getObject()).getVorname() + " " + ((Telefonbuch) event.getObject()).getNachname());
FacesContext.getCurrentInstance().addMessage("eintraege-list", msg);
}
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("Eintrag ausgewählt",
((Telefonbuch) event.getObject()).getVorname() + " " + ((Telefonbuch) event.getObject()).getNachname());
FacesContext.getCurrentInstance().addMessage("eintraege-list", msg);
}
@Override
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setSelectedEntries(List<Telefonbuch> selectedEntries) {
this.selectedEntries = selectedEntries;
}
public void setSelectedEntry(Telefonbuch selectedEntry) {
this.selectedEntry = selectedEntry;
}
型号:
@Data
@Entity
public class Telefonbuch {
public enum Gender {
MALE("Männlich"), FEMALE("Weiblich");
private String shortGender;
private Gender(String shortGender) {
this.shortGender = shortGender;
}
public String getShortGender() {
return shortGender;
}
}
@Column
@Enumerated(EnumType.STRING)
private Gender gender;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String vorname;
@Column
private String nachname;
@Column
private String telefonnummer;
@Column
private String handynummer;
@Column
private String geschaeftsstelle;
protected Telefonbuch() {
}
public Telefonbuch(String vorname, String nachname, String telefonnummer, String handynummer) {
this.vorname = vorname;
this.nachname = nachname;
this.telefonnummer = telefonnummer;
this.handynummer = handynummer;
}
PrimeFaces 6.2版
JSF MyFaces版本2.2.12
Java 1.8
答案 0 :(得分:2)
使用您的方法
TelefonbuchListController.loadData() {
lazyModel = new LazyDataModel<Telefonbuch>() {
//...
}
您将创建abstract
类LazyDataModel
的新匿名实例。然后,将其分配给lazyModel
字段,该字段随后返回到您的p:dataTable
value
属性。
显然,它不会覆盖来自getRowKey
类getRowData
的非有效abstract
或LazyDataModel
方法。
您将必须像这样覆盖它们:
public void loadData() {
lazyModel = new LazyDataModel<Telefonbuch>() {
// ...
@Override
public Telefonbuch getRowData(String rowKey) {
// your implementation here
}
@Override
public Object getRowKey(Telefonbuch telefonbuch) {
// your implementation here
}
// ...
}
您在问题中提出的方法getRowKey
和getRowData
都属于一个LazyDataModel
实现,该实现未分配给p:dataTable
value
属性。因此,两者都不会被调用。如果它是分配给LazyDataModel
p:dataTable
属性的value
,则您的p:dataTable
可能看起来像这样:
<p:dataTable id="table"
var="telefonbuch"
lazy="true"
widgetVar="tableWv"
value="#{telefonbuchList}"
...