2009-04-09 68 views
3

我 - 不幸 - 与jsf一起工作,我遇到问题。 我有一个jsf页面,它使用<h:dataTable>组件显示包含一些数据的表格。 此表的每一行都有一个<h:commandLink>,带有删除操作以删除该行中的项目。 当我执行该操作,在支持bean的方法是否正确调用,ArrayList中包含该表项是正确uptaded和导航方法回来在同一个页面,该表是被正确地执行。为什么在从数据库加载辅助bean中的新数据后,jsf视图不会更新?

时重新加载页面表未更新。我看到删除操作之前表中的相同项目。

如果我再重新加载页面,现在的表被更新。

这似乎就像之前的支持Bean已经完成了更新视图渲染。

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

这里是一些代码:

的commandLink在JSF页面,数据表中:

<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。 我已经试过给它的会话范围,并调用一个方法来更新列表,但结果是一样的。

我希望我已经够清楚了。感谢大家提前。


更新到这问那改变了一切

感谢大家。正如McDowell所说,问题并不在于视图呈现时,问题根本不在JSF中。

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

有此两个日期之间的差异的第二部分分数,这就是为什么我能看到最新的名单就在我重新加载页面:因为一个矿2秒获得通过!

也许这个问题可能对别人有用。

回答

4

看起来就像观点是呈现 之前支持bean 已经完成了更新。

这可能发生的唯一方法是,如果你在另一个线程中完成了工作 - 但它看起来并不像你正在做的那样。

我猜测,但它看起来像一个逻辑问题在你的支持豆。您的servicesListBean保持状态?那就是:

  1. HTTP POST
  2. 恢复视图生命周期的相将导致servicesListBean在请求范围(生命周期的每个阶段需要每一行迭代)
  3. 创建servicesListBean从持久性存储中提取行并将它们缓存在bean状态
  4. 当我们到达INVOKE APPLICATION阶段时,removeServizio()去除持久性存储目标行,但不会做任何事情缓存Bean状态
  5. 渲染响应阶段如果你现在刷新呈现过时缓存Bean状态
  6. ,豆得重新创建新的缓存值,你会看到正确的状态

支持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 
    } 

} 
1

如果您没有明确重定向到“另一个”页面(即使它是相同的页面),您将获得旧数据。这是功能。尝试像这样:

public String removeServizio() { 
    . 
    . 
    . 
    userSessionBean.goToElencoServizi(); // if this redirects to needed page 
    return null; 
} 
相关问题