You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExtJS Modern Toolkit下Grid嵌套对象展示与子对象REST操作实现方案(基于RowExpander)

Solution for ExtJS Modern Grid with RowExpander and Child REST Operations

Got it, let's tackle this step by step. Since you're using the Modern Toolkit, RowExpander is exactly the right approach here. We'll set it up to display the movieRentals child records, then wire up the POST functionality for returning individual movies.

Step 1: Update the Parent Grid with RowExpander

First, let's fix your existing grid configuration—your original "Movie" column was pointing to a non-existent field, so we'll clean that up and add the RowExpander plugin to render child grids:

Ext.define('Vidly.view.rental.DisplayRentalsView', {
    extend: 'Ext.grid.Grid',
    xtype: 'displayrentalsview',
    reference: 'rentallist',
    title: 'Rental List',
    controller: 'displayrentalsviewcontroller',
    viewModel: 'rentalsviewmodel',
    reference:'displayrentalsviewgrid',
    selType: 'rowmodel',
    selModel: { mode: 'SINGLE' },
    viewConfig: { stripeRows: true },
    listeners: { 
        selectionchange: 'onSelectionChange', 
        show: 'onShow' 
    },
    bind: { store: '{RentalListStore}' },
    itemConfig: { viewModel: true },
    plugins: [
        'pagingtoolbar',
        {
            type: 'rowexpander',
            // Define the child grid that appears when expanding a parent row
            item: {
                xtype: 'grid',
                reference: 'childMovieGrid',
                columns: [
                    { text: "Movie Title", flex: 2, dataIndex: 'movie' },
                    { 
                        text: "Date Returned", 
                        flex: 1, 
                        dataIndex: 'dateReturned',
                        renderer: function (value) {
                            if (value) {
                                return Ext.Date.format(new Date(value), 'm/d/Y');
                            }
                            return 'Not Returned';
                        }
                    },
                    {
                        text: 'Actions',
                        width: 120,
                        cell: {
                            tools: {
                                returnMovie: {
                                    iconCls: 'x-fa fa-check-circle',
                                    tooltip: 'Return Movie',
                                    handler: 'onReturnMovieClick'
                                }
                            }
                        }
                    }
                ],
                // Bind the child grid's data to the parent record's movieRentals array
                bind: {
                    store: '{record.movieRentals}'
                }
            }
        }
    ],
    items: [
        { 
            xtype: 'container', 
            docked: 'top', 
            items: [
                { 
                    docked: 'left', 
                    xtype: 'button', 
                    ui: 'decline', 
                    itemId: 'returnRental', 
                    text: 'Return Rental', 
                    reference: 'btnReturnRental', 
                    handler: 'onReturnClick', 
                    disabled: true 
                }
            ] 
        }
    ],
    columns: [
        { 
            text: "Customer", 
            flex: 1, 
            dataIndex: 'customer' 
        },
        { 
            text: "Date Rented", 
            flex: 1, 
            dataIndex: 'dateRented',
            renderer: function (value) {
                if (value) {
                    return Ext.Date.format(new Date(value), 'm/d/Y');
                }
                return '';
            } 
        }
    ]
});

Step 2: Add Controller Logic for POST Operations

Next, update your displayrentalsviewcontroller to handle the return movie action, sending a POST request to your API and updating the local record on success:

Ext.define('Vidly.view.rental.DisplayRentalsViewController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.displayrentalsviewcontroller',

    // Keep your existing handlers here
    onSelectionChange: function() { /* Your existing code */ },
    onShow: function() { /* Your existing code */ },
    onReturnClick: function() { /* Your existing code */ },

    // New handler for returning individual movies
    onReturnMovieClick: function(gridTool, cell) {
        // Grab the child movie rental record from the clicked cell
        const movieRecord = cell.getRecord();
        const rentalId = movieRecord.get('rentalDetailDtoId');
        const movieId = movieRecord.get('id');

        // Prepare payload matching your API's requirements
        const postData = {
            id: movieId,
            rentalDetailDtoId: rentalId,
            dateReturned: new Date().toISOString()
        };

        // Send POST request to your API endpoint
        Ext.Ajax.request({
            url: '/api/movieRentals/return', // Replace with your actual API URL
            method: 'POST',
            jsonData: postData,
            success: (response) => {
                // Update the local record to reflect the returned status immediately
                movieRecord.set('dateReturned', postData.dateReturned);
                Ext.Msg.alert('Success', 'Movie marked as returned!');
            },
            failure: (response) => {
                Ext.Msg.alert('Error', 'Failed to process return. Please try again.');
            }
        });
    }
});

Key Details Explained

  • RowExpander Binding: The child grid's store is directly bound to the parent record's movieRentals array using {record.movieRentals}, so it automatically loads the correct child data when a row is expanded.
  • Child Grid Actions: We added a tool button in the child grid's "Actions" column to trigger the return operation. The handler grabs the relevant record data, constructs the POST payload, and sends the request.
  • Local Record Update: After a successful POST, we update the child record's dateReturned field locally—no need to reload the entire store for instant feedback.
  • Column Cleanup: Removed invalid columns from the parent grid (since movie details belong to the child records) to keep the parent view focused on top-level rental info.

内容的提问来源于stack exchange,提问作者Samuel Marvin Aguilos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:07:39