【问题标题】:Reload ADF table after button click in a Fusion Web application在 Fusion Web 应用程序中单击按钮后重新加载 ADF 表
【发布时间】:2021-05-30 18:04:41
【问题描述】:

我最近开始使用 JDeveloper 12c 处理我的第一个 ADF 项目。

所以,我有一个连接到 Oracle 数据库的 Fusion Web 应用程序。在其中一个 jsf 页面上有两个 ADF 表,它们显示来自数据库的数据。下面是一个向数据库发送“DELETE”语句以删除选定条目的按钮。由于原因,两个表必须在此之后刷新(删除会影响两个表的显示条目)。

在我已经很高兴表格显示正确的数据并且按钮也完成了它之后,我很快意识到如果数据库发生更改,jsf 页面中的表格将不会自动刷新。我在网上搜索了一些关于如何在 ADF Fusion 应用程序中刷新 jsf 页面元素的入门级教程。遗憾的是,到目前为止,我还没有找到任何可以给我打开它的钥匙的东西。

我在Oracle HQ页面找到this article,但是它也有使用很多专有命名的习惯,并且是用流畅的文本编写的,所以里面没有代码示例或sn-p或类似的东西,所以它新手很难跟上。

这是来自我的托管 java bean 的 sn-p,我在其中存储按钮功能:

    public String update() {
    getDBConnection c = new DBConnection();
    Connection conn = c.getConn();
    
    RowKeySet selectedEntries = getDetailTable().getSelectedRowKeys();   
    Iterator selectedEntryIter = selectedEntries.iterator();
    DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
    DCIteratorBinding entryIter = bindings.findIteratorBinding("my_iterator");
    RowSetIterator rSIter = entryIter.getRowSetIterator();
    try {
        PreparedStatement pstmt1 = conn.prepareStatement("DELETE ...");
        PreparedStatement pstmt2 = conn.prepareStatement("DELETE ...");
        while(selectedEntryIter.hasNext()){
            Key key = (Key)((List)selectedEntryIter.next()).get(0);
            Row currentRow = rSIter.getRow(key);
            BigDecimal barcode = (BigDecimal) currentRow.getAttribute("id");
            BigDecimal field1 = (BigDecimal) currentRow.getAttribute("field1");
            BigDecimal field2 = (BigDecimal) currentRow.getAttribute("field2");
                          
            pstmt1.setBigDecimal(1, id);
            pstmt1.setBigDecimal(2, field1);
            pstmt2.setBigDecimal(1, id);
            pstmt2.setBigDecimal(2, field2);
            pstmt1.executeUpdate();
            pstmt2.executeUpdate();
            
        }
        conn.commit();
        //i guess here i have to trigger to refresh the tables but I have pretty to no clue of how to do that
        //where do I have to set the functionality? I read sth about creating another bean in the "session" package 
        //but somehow i have to access the jsf i want to have refreshed. Where do I create that connection?
        //even a simple example or a good reference to a  tutorial would be helpful for me
        
    } catch (SQLException e) {
        System.out.println(e.getMessage());
    }
    return null;
}

可能这个问题与一个已经存在的问题重复,我太愚蠢了,找不到它,但无论如何我都会试一试。提前致谢!

【问题讨论】:

    标签: java sql oracle oracle-adf jdeveloper


    【解决方案1】:

    在您的情况下,您可以简单地添加一个 entryIter.executeQuery();就在你的 conn.commit(); (您还应该避免运行直接 sql delete 并使用标准 ADF BC DELETE https://o7planning.org/11489/create-update-and-delele-data-using-adf-form-in-adf-bc#a9769791

    但是为了回答未来查询的问题标题,下面是一个简单的刷新表格按钮的示例,易于重复使用,我通常将其添加到我的客户表格工具栏上:

    //in your jsff
    <af:panelCollection id="pc" >
        <f:facet name="menus"/> 
        <f:facet name="statusbar"/>
        <f:facet name="toolbar">
            <af:toolbar id="t1" flex="5">
                <af:group id="g1">
                    <af:commandImageLink shortDesc="Reload" partialSubmit="true" actionListener="#{YOUR_SCOPE.YOUR_BEAN.refreshTable}"
                                         icon="#{resource['images:YOUR_RELOAD_ICON.png']}">
                        <f:attribute name="tableIdToRefresh" value="YOUR_TABLE_ID"/>
                    </af:commandImageLink>
                </af:group>
            </af:toolbar>
            </f:facet>
            <af:table id="YOUR_TABLE_ID" value="#{bindings.YOUR_VO.collectionModel}" var="row" rows="#{bindings.YOUR_VO.rangeSize}"
                      selectedRowKeys="#{bindings.YOUR_VO.collectionModel.selectedRow}" selectionListener="#{bindings.YOUR_VO.collectionModel.makeCurrent}" rowSelection="single"
                      fetchSize="#{bindings.YOUR_VO.rangeSize}" filterModel="#{bindings.XxcnVieIntSearchVCQuery.queryDescriptor}"
                      queryListener="#{bindings.XxcnVieIntSearchVCQuery.processQuery}" varStatus="vs" >
                
                <!--  COLUMNS -->
            </af:table>
    </af:panelCollection>
    
    
    //in your bean #{YOUR_SCOPE.YOUR_BEAN.refreshTable}
    public void refreshTable(ActionEvent actionEvent) {
        //Get the attribute tableIdToRefresh value. I like to have it as a jsff attribute so i can easily reuse the button elsewhere
        String tableToRefreshId = "" + ((RichCommandImageLink)actionEvent.getSource()).getAttributes().get("tableIdToRefresh");
        if (sValeurCode != null) {
            addPprToComponentById(tableToRefreshId);
            //If it doesn't suffice (see below) you can use this : 
            //refreshTableIterator(tableToRefreshId);
        }
    }
    
    public static void addPprToComponentById(String id) {
        Object component = findComponentInRoot(id); //from the great JSFUtils library
        if (component != null) {
            AdfFacesContext.getCurrentInstance().addPartialTarget((UIComponent)component);
            AdfFacesContext.getCurrentInstance().partialUpdateNotify((UIComponent)component);
        }
    }
    
    /**
     * Locate an UIComponent in view root with its component id. Use a recursive way to achieve this.
     * @param id UIComponent id
     * @return UIComponent object
     */
    public static UIComponent findComponentInRoot(String id) {
        UIComponent component = null;
        if (id != null) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            if (facesContext != null) {
                UIComponent root = facesContext.getViewRoot();
                if (root != null) {
                    component = findComponent(root, id);
                }
            }
        }
        return component;
    }
    

    您也可以将此 addPPR 逻辑用于其他组件。

    如果一个简单的 ppr 还不够。您可以使用这些强制执行表查询:

    public static void refreshTableIterator(String tableId) {
        RichTable table = findComponentInRoot(tableId);
        DCIteratorBinding treeIterator = null;
        if (table != null) {
            treeIterator = getTableIterator(table);
            if (treeIterator != null) {
                RowSetIterator rsi = treeIterator.getRowSetIterator();
                treeIterator.executeQuery();
                rsi.closeRowSetIterator();
            }
        }
    }
    
    public static DCIteratorBinding getTableIterator(RichTable table) {
        DCIteratorBinding treeIterator = null;
        CollectionModel model = (CollectionModel)table.getValue();
        if (model != null) {
            JUCtrlHierBinding treeBinding = (JUCtrlHierBinding)model.getWrappedData();
            if (treeBinding != null) {
                treeIterator = treeBinding.getDCIteratorBinding();
            }
        }
        return treeIterator;
    }
    

    【讨论】:

    • 抱歉,到目前为止我没有对此做出反应,我目前正在尝试根据您的回答实施解决方案,但这需要一段时间。我是 ADF 的血腥菜鸟,Jdeveloper 通过 VPN(家庭办公室)表现不稳定,背后的过程对我来说也是全新的。尽管如此,感谢您的努力,我们将看看它是否会打开成功之门
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 2012-04-07
    • 2018-11-13
    • 2021-01-27
    • 2012-11-14
    • 2018-10-15
    • 1970-01-01
    相关资源
    最近更新 更多