JSF 在对话框编辑记录后使用 AJAX 更新数据表,该记录已使用 actionListener 完全填充

JSF update datatable using AJAX after dialog edit of record which was fully populated using actionListener

提问人:jeff 提问时间:11/2/2023 更新时间:11/7/2023 访问量:34

问:

我有一个PrimeFaces数据表,每行上都有编辑按钮,可以打开Primefaces动态对话框,但是为了克服对话框呈现时的LazyLoad异常,我用来重新查询数据库并完全填充。actionListenerselectedItem

在对话框中更新记录后,数据不会刷新。我知道我是正确的,并意识到问题是因为我更新的对象不是表中引用的实际对象,而是在 actionListener 中实例化的新完全加载对象。update=

我的解决方法是在完全加载的情况下使用并重新设置列表中的该值 这是正确的方法还是黑客?如果对象的等值编码不正确,可能会适得其反。indexOfselectedItem

public void update() {     
   dataService.update(selectedItem);
   listOfItems.set(listOfItems.indexOf(selectedItem), selectedItem); <-Typically done?
}


以下是我的方法的更多详细信息
<h:form id="formId">
<p:dataTable id="dataTableId" value="#{dataManagerView.listOfItems}" var="item">

<p:column headerText="Action">
   <p:commandButton oncomplete="PF('editDialogWv').show()" update=":outlookDialogId" 
          actionListener="#{dataManagerView.loadDataViewDetails(item)}" >
       <ui:remove>Cannot do just this due to LazyLoad Exception
          <f:setPropertyActionListener value="#{item}" target="#{dataManagerView.selectedItem}" />
       </ui:remove>
   </p:commandButton>
</p:column>
</p:dataTable>
</h:form>
public void loadDataViewDetails(Item item) {
    // Called from actionListener
    selectedItem = dataService.retrieveFullById(item.getId());
}
<p:dialog id="outlookDialogId" dynamic="true" widgetVar="outlookDialogWv" >
   <h:form id="outlookFormId">
         bunch of form input boxes
     <p:commandButton update="formId:dataTableId" action="#{dataManagerView.update()}">
   </p:commandButton>
   </h:form>
</p:dialog>
public void update() {
   dataService.update(selectedItem); //The selected item only refreshes in table if I manually refresh browser 
}

这可行,但这是正确的方法吗?

public void update() {
   dataService.update(selectedItem);
   listOfItems.set(listOfItems.indexOf(selectedItem), selectedItem);
}
AJAX JSF

评论


答:

1赞 BalusC 11/5/2023 #1

这可行,但这是正确的方法吗?

没关系。前提是该方法仅检查技术相等性(例如生成的密钥)而不是自然相等性(整个对象,即所有属性)。否则,对所选项目所做的更改可能会导致返回 .更安全的是:equals()equals()false

public void loadDataViewDetails(Item item) {
    originalSelectedItem = item;
    selectedItem = dataService.retrieveFullById(item.getId());
}
public void update() {     
   dataService.update(selectedItem);
   listOfItems.set(listOfItems.indexOf(originalSelectedItem), selectedItem);
}

但通常您只需从服务中重新加载整个列表/页面,以确保所有其他项目也反映最新更改,以防其他人同时对其进行编辑。F.D.(英语:F.D.)

public void update() {     
   dataService.update(selectedItem);
   listOfItems = dataService.getListOfItems();
}

另请参阅:

评论

0赞 jeff 11/7/2023
重新加载整个列表的好点,最好是分页,以确保它是最新的。我总是采取不重新加载列表的立场,认为这是浪费,因为我已经在内存中拥有它并且数据库调用很昂贵。但它肯定会使重新加载并从新状态开始的事情变得更加容易。