gpt4 book ai didi

java - 为什么从数据库加载支持 bean 中的新数据后 jsf View 没有更新?

转载 作者:搜寻专家 更新时间:2023-11-01 02:34:54 24 4
gpt4 key购买 nike

不幸的是,我正在使用 jsf,但遇到了问题。我有一个 jsf 页面,它使用 <h:dataTable> 显示一个包含一些数据的表格。成分。此表的每一行都有一个 <h:commandLink>使用删除操作删除该行中的项目。当我执行该操作时,支持 bean 中的方法被正确调用,包含表项的 ArrayList 被正确更新,并且导航方法返回到表所在的同一页面,正确执行。

但是当页面重新加载时,表格没有更新。我看到删除操作之前表格中的相同项目。

如果我再次重新加载页面,现在表格已更新。

似乎在支持 bean 完成更新之前呈现 View 。

如何在支持 bean 完成更新时强制呈现 View ?

这里是一些代码:

jsf 页面中的 commandLink,在 dataTable 中:

<h:column>
<f:facet name="header">
<h:outputText value="Rimuovi" />
</f:facet>
<h:commandLink action="#{servicesListBean.removeServizio}" title="Rimuovi questo servizio" onclick="if(!confirm('Vuoi davvero rimuovere questo servizio?')) return false">
<h:outputText value="Rimuovi" />
</h:commandLink>
</h:column>

这里是支持 bean 中的方法:

public String removeServizio() {
this.servizioToRemove = (Servizio) getDataTable().getRowData();
try {
ServiziDAO.removeServizio(this.servizioToRemove.getId());
} catch (Exception e) {
// ...
}

return userSessionBean.goToElencoServizi();
}

在这种情况下,我将 请求范围 赋予了辅助 bean。我已经尝试给它 session 范围并调用一个方法来更新列表,但结果是一样的。

希望我说得足够清楚。提前感谢大家。


这个问题的更新改变了一切

谢谢大家。正如 McDowell 所说,问题不在呈现 View 的时间,问题根本与 JSF 无关。

发生的事情是,当我从数据库中删除一个项目时,我没有删除该行,我只是为该项目设置了一个结束日期。这是在我的应用程序中执行此操作的正确方法,但是在将结束日期设置为项目的查询中,我花时间使用了 System.currentTimiMillis() ,在重新加载更新列表的查询中,我使用了 sysdate Oracle 服务器。

这两个日期之间有几分之一秒的差异,这就是为什么我可以在重新加载页面时看到更新的列表:因为已经过了一秒或两秒!

也许这个问题对其他人有用。

最佳答案

It seems just like the view is rendered before that the backing bean has completed its updates.

发生这种情况的唯一方法是您在另一个线程中完成工作 - 但看起来您并没有这样做。

我在猜测,但它看起来像是您的支持 bean 中的逻辑问题。您的servicesListBean 是否保持状态?即:

  1. HTTP 发送
  2. 生命周期的RESTORE VIEW阶段导致在请求范围内创建servicesListBean(生命周期的每个阶段都需要遍历每一行)
  3. servicesListBean 从持久性存储中获取行并将它们缓存在 bean 状态中
  4. 当我们进入INVOKE APPLICATION 阶段时,removeServizio() 会从持久存储中删除目标行,但不会对缓存的 bean 状态做任何事情<
  5. RENDER RESPONSE 阶段呈现陈旧的缓存 bean 状态
  6. 如果您现在刷新,将使用新的缓存值重新创建 bean,您会看到正确的状态

这个支持 bean 重现了这个问题:

public class DeleteFromRowBean {

private ListDataModel dataModel;

public DataModel getList() {
if (dataModel == null) {
List<RowBean> list = PersistenceStore.fetch();
dataModel = new ListDataModel(list);
}
return dataModel;
}

public String deleteCurrentRow() {
if (dataModel == null) {
throw new IllegalStateException();
}
RowBean row = (RowBean) dataModel.getRowData();
PersistenceStore.delete(row.getId());
return null; // no navigation required
}

}

在数据表迭代时修改列表不是一个好主意(你会得到并发修改异常)。我的示例 bean 中最简单的解决方案就是释放对缓存数据的引用。在 INVOKE APPLICATION 阶段的迭代期间,数据表已经有对此的引用;当 RENDER RESPONSE 开始时,数据表将再次调用 getList(),导致从持久性存储中获取新状态。

public class DeleteFromRowBean {

private ListDataModel dataModel;

public DataModel getList() {
if (dataModel == null) {
List<RowBean> list = PersistenceStore.fetch();
dataModel = new ListDataModel(list);
}
return dataModel;
}

public String deleteCurrentRow() {
if (dataModel == null) {
throw new IllegalStateException();
}
RowBean row = (RowBean) dataModel.getRowData();
PersistenceStore.delete(row.getId());
// flush cached data
dataModel = null;
return null; // no navigation required
}

}

关于java - 为什么从数据库加载支持 bean 中的新数据后 jsf View 没有更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/733674/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com