带有表单 cals servlet 的 Ext.js 4 窗口返回 JSON 但无法填充网格面板

Posted

技术标签:

【中文标题】带有表单 cals servlet 的 Ext.js 4 窗口返回 JSON 但无法填充网格面板【英文标题】:Ext.js 4 window with form cals servlet which returns JSON but unable to populate gridpanel 【发布时间】:2012-04-04 17:31:44 【问题描述】:

我正在使用带有 MVC 的 Ext.js 4。我有一个弹出窗口,并询问用户一些标准。该窗口调用一个 servlet,它以 JSON 格式返回数据,然后应该填充一个网格。我可以通过 Firefly 看到 JSON 对象被返回。但是,网格没有被填充。原因是对 servlet 的后续调用是有必要的。这是因为我在两个地方指定了 URL。我知道这是错误的,但如果省略其中一个,我会收到错误消息。

这是 app/controller/PSLocators.js

Ext.define('MyApp.controller.PSLocators', 
    extend: 'Ext.app.Controller',
    stores: [ 'PSLocators' ],
    models: [ 'PSLocator' ],
    views : [ 'pslocator.List' ]
);

这是 app/model/PSLocator.js

Ext.define('MyApp.model.PSLocator', 

    extend: 'Ext.data.Model',
    fields: 
    [
        'id', 
        'name',
        'address',
        'city',
        'state',
        'zip',
    ]
);

这是app/store/PSLocators.js。这有第一个网址。这是不返回任何数据的那个。我认为我不应该在此处使用代理,但如果我删除代理 ,我会收到错误消息

uncaught exception: [Exception... "'You are using a ServerProxy but have not supplied it with a url.' when calling method: [nsIDOMEventListener::handleEvent]" 
nsresult: "0x8057001c (NS_ERROR_XPC_JS_THREW_JS_OBJECT)" 
location: "JS frame :: chrome://firebug/content/net/spy.js :: callPageHandler :: line 812" data: no]"


Ext.define('MyApp.store.PSLocators', 
    extend: 'Ext.data.Store',
    model: 'MyApp.model.PSLocator',
    autoLoad: false,    // see also activate() in grid panel
    sortOnLoad: false,  // sorted by SAS
    proxy: 
    
        type: 'ajax',
        url: MyGlobalData.contextPath + '/PSLocator',
        reader: 
        
            type: 'json',
            root: 'data',  // the name of the array within the JSON dataset
            totalProperty: 'results',
            successProperty: 'success'
        
    
);

这是app/view/pslocator/List.js。这有第二个网址。此 url 以 JSON 格式正确返回数据。如果我删除 url,我会收到错误消息“未捕获的异常:未指定 URL”

Ext.define('MyApp.view.pslocator.List' ,
    extend: 'Ext.grid.Panel',
    alias : 'widget.pslocatorlist',
    store : 'PSLocators',
    title : 'Store Locator',
    id    : 'pslocator.List',

    autoScroll: true,
    height: 400,
    columnLines: true,

    initComponent: function()
    
        this.columns = [
            header: 'ID'          , dataIndex: 'id'        , flex: .05 , align: 'center' ,
            header: 'Name'        , dataIndex: 'name'      , flex: .20 , align: 'left'   ,
            header: 'Address'     , dataIndex: 'address'   , flex: .20 , align: 'left'   ,
            header: 'City'        , dataIndex: 'city'      , flex: .10 , align: 'left'   ,
            header: 'State'       , dataIndex: 'state'     , flex: .05 , align: 'center' ,
            header: 'Zip'         , dataIndex: 'zip'       , flex: .05 , align: 'center' 
        ];

        this.callParent(arguments);
    ,

    listeners:
    
        activate: function()
        
            this.un('activate', arguments.callee);
            var win = new Ext.Window(
            
                id: 'id-pslocator-window',
                title: 'Show locations near which store?',
                items: [
                
                    xtype      : 'form',
                    id         : 'id-pslocator-form',
                    bodyPadding: 5,
                    width      : 500,
                    height     : 125,
                    autoScroll : false,

                    // The form will submit an AJAX request to this URL when submitted
                    url: MyGlobalData.contextPath + '/PSLocator',

                    layout: 'auto',

                    defaults: 
                    
                        anchor: '100%'
                    ,

                    items: [
                    
                        xtype       : 'textfield',
                        fieldLabel  : 'Store number',
                        name        : 'pStoreNumber',
                        labelWidth  : 200,
                        width       : 300,  // includes labelWidth
                        allowBlank  : false,
                        regex       : /^([0-9]+)([ ]*)$/,  
                        regexText   : 'Must be a single unsigned integer.',
                    
                ],

                // Reset and Submit buttons
                buttons: [
                    
                        text: 'Reset',
                        handler: function() 
                        
                            this.up('form').getForm().reset();
                        
                    ,
                    
                        text: 'Submit',
                        formBind: true, //only enabled once the form is valid
                        disabled: true,
                        handler: function() 
                        
                            var form = this.up('form').getForm();
                            if (form.isValid()) 
                            
                                form.submit(
                                
                                    success: function(form, action) 
                                    
                                        console.log('In success function');
                                        var myGrid = Ext.getCmp('id-pslocator-panel');
                                        console.log('myGrid = ' + myGrid);
                                        var myStore = myGrid.getStore();
                                        console.log('myStore = ' + myStore);
                                        myStore.load();  /* requires store be defined as above */
                                        myGrid.getView().refresh();

                                        var myPopup = Ext.getCmp('id-pslocator-window');
                                        myPopup.destroy();

                                      // end success function
                                );  // end form submit
                              // end if is valid
                          // end handler
                       //  end submit
                ]   // end buttons
                ]  // end items
            ); // end win

            win.show();
            // this.store.load();
        
    
);  // Ext.define

有人可以帮忙,或者给我一个工作示例(提醒:我正在尝试使用 MVC 架构。)

【问题讨论】:

【参考方案1】:

您应该将代理配置存储在模型中,而不是存储在 ExtJS4 中。此外,您似乎只是想将您的商店搜索限制为特定的商店编号。您不需要通过表单提交 POST 请求来执行此操作。您应该为您的商店添加一个过滤器,以便服务器可以返回正确的数据。

免责声明:我没有测试过这段代码,但它应该足以让你继续前进。

app/model/PSLocator.js

Ext.define('MyApp.model.PSLocator', 

    extend: 'Ext.data.Model',
    fields: 
    [
        'id', 
        'name',
        'address',
        'city',
        'state',
        'zip',
    ],
    proxy: 
    
        type: 'ajax',
        url: MyGlobalData.contextPath + '/PSLocator',
        reader: 
        
            type: 'json',
            root: 'data',  // the name of the array within the JSON dataset
            totalProperty: 'results',
            successProperty: 'success'
        
    
);

app/store/PSLocators.js

Ext.define('MyApp.store.PSLocators', 
    extend: 'Ext.data.Store',
    model: 'MyApp.model.PSLocator',
    autoLoad: false,    // see also activate() in grid panel
    sortOnLoad: false,  // sorted by SAS,
    remoteFilter: true  // Needed so filter changes will go to the server
);

app/view/pslocator/List.js

Ext.define('MyApp.view.pslocator.List' ,
    extend: 'Ext.grid.Panel',
    alias : 'widget.pslocatorlist',
    store : 'PSLocators',
    title : 'Store Locator',
    id    : 'pslocator.List',

    autoScroll: true,
    height: 400,
    columnLines: true,

    initComponent: function()
    
        this.columns = [
            header: 'ID'          , dataIndex: 'id'        , flex: .05 , align: 'center' ,
            header: 'Name'        , dataIndex: 'name'      , flex: .20 , align: 'left'   ,
            header: 'Address'     , dataIndex: 'address'   , flex: .20 , align: 'left'   ,
            header: 'City'        , dataIndex: 'city'      , flex: .10 , align: 'left'   ,
            header: 'State'       , dataIndex: 'state'     , flex: .05 , align: 'center' ,
            header: 'Zip'         , dataIndex: 'zip'       , flex: .05 , align: 'center' 
        ];

        this.callParent(arguments);
    
);  // Ext.define

app/view/pslocator/Window.js

Ext.define('MyApp.view.pslocator.Window', 
    extend: 'Ext.Window',
    alias: 'widget.storeselector',
    id: 'id-pslocator-window',
    title: 'Show locations near which store?',
    items: [
    
        xtype      : 'form',
        id         : 'id-pslocator-form',
        bodyPadding: 5,
        width      : 500,
        height     : 125,
        autoScroll : false,

        // The form will submit an AJAX request to this URL when submitted
        url: MyGlobalData.contextPath + '/PSLocator',

        layout: 'auto',

        defaults: 
        
            anchor: '100%'
        ,

        items: [
        
            xtype       : 'textfield',
            fieldLabel  : 'Store number',
            name        : 'pStoreNumber',
            labelWidth  : 200,
            width       : 300,  // includes labelWidth
            allowBlank  : false,
            regex       : /^([0-9]+)([ ]*)$/,  
            regexText   : 'Must be a single unsigned integer.',
        
    ],

    // Reset and Submit buttons
    buttons: [
        
            text: 'Reset',
            handler: function() 
            
                this.up('form').getForm().reset();
            
        ,
        
            text: 'Submit',
            formBind: true, //only enabled once the form is valid
            disabled: true,
            handler: function() 
            
                var form = this.up('form').getForm();
                if (form.isValid()) 
                
                    this.fireEvent('storeselected', form.getValues().pStoreNumber);
                    this.destroy();
                  // end if is valid
              // end handler
           //  end submit
    ]   // end buttons
    ]  // end items
);

app/controller/PSLocators.js

Ext.define('MyApp.controller.PSLocators', 
    extend: 'Ext.app.Controller',
    stores: [ 'PSLocators' ],
    models: [ 'PSLocator' ],
    views : [ 'pslocator.List' ],
    init: function() 
        this.control(
            'pslocatorlist': 
                activate: this.showStoreSelector
            ,
            'storeselector': 
                storeselected: this.updatePSLocatorStore
            
        );
    ,

    showStoreSelector: function()
    
        var win = Ext.create('MyApp.view.pslocator.Window');
        win.show();
    ,

    updatePSLocatorStore: function(storeId) 
        this.getPSLocationsStore().filter('id', storeId);
        this.getPSLocationsStore().load(); // I can't remember if this step is needed.
    
);

我认为这就是我通过阅读代码所能得到的最好的结果。它应该让您了解如何利用 MVC 技术来发挥自己的优势,并有望让您走上正确的道路。

【讨论】:

感谢您的努力。我真诚地感谢它。我回来晚了,因为另一个“匆忙”的任务进来了。(不是总是这样吗?)我尝试进行您推荐的更改,但仍然无法正常工作。可能是我自己的理解不够。尽管如此,我对这里推荐的过滤感到不舒服。除非我有误解,否则此解决方案是依靠服务器返回所有记录,并由客户端进行过滤。有很多记录要返回。 没有配置选项可以将所有过滤请求发送到服务器。 别担心 Bill :) 没有配置选项,可以将所有过滤请求发送到服务器。在商店设置中,您可以配置以下内容。 remoteFilter: true 以便过滤器作为查询变量发送到您的 Web 服务。就像这样 /PSLocator?filterName=filterValue 从您的原始帖子看起来您正在发送 POST 以过滤表单提交上的商店位置。所以除非你的服务器端应用程序保持状态?这不会影响您的商店数据。您要做的是在正确的 storeID 时更新商店过滤器并重新加载商店。 最终,我的解决方案是使用 extraParams 选项。

以上是关于带有表单 cals servlet 的 Ext.js 4 窗口返回 JSON 但无法填充网格面板的主要内容,如果未能解决你的问题,请参考以下文章

如何通过Javascript提交带有自定义变量的表单?

根据要求完成表单以及使用servlet处理表单 任务要求 掌握Servlet输出表单和接收表单数据(多值组件的读取)。

JSP怎么将表单提交到对应的servlet

servlet获取不到表单数据?

html表单数据为啥不能提交到servlet

在html中建一个form表单 如何向servlet提交数据