Проблема заключается в том, что PrimeFaces 'LazyDataModel
не сохраняет полную модель данных, отображаемых в представлении. Он отслеживает только что загруженные элементы и отбрасывает старые элементы. Это делает невозможным доступность этих элементов из JSF.
Но поскольку вы все равно подклассифицируете этот класс (он абстрактный), довольно легко изменить это поведение. В основном, что вы хотите сделать, это отслеживать все загруженные вами данные и возвращать эти данные по запросу. Как минимум, вам необходимо переопределить setRowIndex()
, getRowData()
, isRowAvailable()
и load()
. Ниже приведен пример, который работает для меня.
public class MyLazyModel extends LazyDataModel<SomeType> implements Serializable {
private final List<SomeType> data;
private int rowIndex;
public MyLazyModel() {
super();
data = new ArrayList<>();
}
@Override
public List<SomeType> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
List<SomeType> retData;
if (first >= data.size()) {
retData = ... //Get the data from datasource
data.addAll(retData);
return retData;
} else {
return data.subList(first, Math.min(first + pageSize, data.size()));
}
}
@Override
public void setRowIndex(int index) {
if (index >= data.size()) {
index = -1;
}
this.rowIndex = index;
}
@Override
public SomeType getRowData() {
return data.get(rowIndex);
}
@Override
public boolean isRowAvailable() {
if (data == null) {
return false;
}
return rowIndex >= 0 && rowIndex < data.size();
}
}
Потому что вы никогда не можете быть уверены, что setWrappedData()
(который вызывается после load()
с данными возврата из этого метода) вызывается только один раз, вы должны принять меры против добавления двойников в вашей модели данных. Здесь я делаю это только путем загрузки данных, которые никогда не были загружены до и хранения этих данных в методе load()
, полностью игнорируя setWrappedData()
. Это довольно уродливо и приведет к проблемам синхронизации, если ваша модель никогда не признана недействительной, но она работает. В любом случае, вы можете обойти это, всегда загружая данные и заменяя старый контент на новый, но это не является основной причиной проблемы.
Кроме того, поскольку вы теперь отслеживаете данные в самом методе, вам необходимо переопределить все методы в LazyDataModel
, которые полагаются на LazyDataModel.data
правильной (или, по крайней мере, той подмножестве, которую вы используете).
Заключительное примечание: вы, конечно, должны убедиться, что ваша модель вернулась на страницу JSF, всегда такая же, как обсуждалось here.
Я столкнулся с той же проблемой и ответил на [мой собственный вопрос] (https://stackoverflow.com/questions/25409316/commandlink-not-working-on-a-lazy-loaded-primefaces-datascroller/26222914# 26222914) –