簡體   English   中英

為什么在從數據庫加載輔助bean中的新數據后不更新jsf視圖?

[英]Why the jsf view is not updated after new data in the backing bean are loaded from database?

我 - 不幸的是 - 與jsf一起工作,我遇到了一個問題。 我有一個jsf頁面,使用<h:dataTable>組件顯示包含一些數據的表。 該表的每一行都有一個帶有刪除操作的<h:commandLink> ,用於刪除該行中的項目。 當我執行該操作時,正確調用了輔助bean中的方法,正確地使用包含表項的ArrayList ,並且正確執行了返回到表所在的同一頁面的導航方法。

但是當重新加載頁面時,表格不會更新 我在刪除操作之前看到了表中的相同項目。

如果我再次重新加載頁面,現在表格已更新。

看起來就像在支持bean完成更新之前呈現的視圖一樣。

如何在支持bean完成更新時強制呈現視圖?

這里有一些代碼:

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。 我已經嘗試給它會話范圍並調用一個方法來更新列表,但結果是一樣的。

我希望我很清楚。 感謝大家提前。


對這個改變一切的問題的更新

謝謝大家。 正如McDowell所說,問題不是在呈現視圖的時候,問題根本不是JSF相關的。

發生的事情是,當我從數據庫中刪除一個項目時,我沒有刪除該行,我只是為該項目設置了結束日期。 這是在我的應用程序中執行此操作的正確方法,但是在查詢中將結束日期設置為項目時我使用System.currentTimiMillis() ,在重新加載uptaded列表的查詢中,我使用了sysdate Oracle服務器。

這兩個日期之間存在一些差異,這就是我重新加載頁面時可以看到更新列表的原因:因為一兩秒鍾就過去了!

也許這個問題對其他人有用。

看起來就像在支持bean完成更新之前呈現的視圖一樣。

這可能發生的唯一方法是,如果你在另一個線程中完成了工作 - 但它看起來並不像你那樣做。

我猜,但它看起來像你的支持bean中的邏輯問題。 你的servicesListBean保持狀態嗎? 那是:

  1. HTTP POST
  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
  }

}

如果您沒有明確重定向到“另一個”頁面(即使它是同一頁面),您將獲得舊數據。 這是功能。 嘗試類似的東西:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM