2

我对 ExtJS 的 Sencha 文档感到非常困惑。该文档以入门指南开头,该指南突出并说明了为应用程序的类和源代码设计合适的结构的重要性。但是提供的示例打破了入门指南中规定的所有约定。示例不是将代码分解为适当的模型、存储、视图等类文件,而是作为单个文件提供的,示例源代码在单独的源文件中不易重用。

我从 Portal 示例 ( http://docs.sencha.com/ext-js/4-1/#!/example/portal/portal.html ) 开始,因为这是我想要创建的那种应用程序。我想增强 Portal 示例并添加一个屏幕,该屏幕将显示一个网格并使用 RESTful Web 服务作为数据后端。我已经创建了我只想创建前端的后端。所以我查看了 RESTful 示例(http://docs.sencha.com/ext-js/4-1/#!/example/restful/restful.html

我试图将 RESTful 示例复制到推荐的单独类模式中,例如模型、存储、视图:

模型:

Ext.define('MyLodge.model.Member', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'name',       type: 'string'},
        {name: 'email',      type: 'string'},
        {name: 'href',       type: 'string'}
    ]
});

店铺:

Ext.require('MyLodge.model.Member');

Ext.define('MyLodge.store.Members', {
    autoLoad: true,
    autoSync: true,
    model: 'MyLodge.model.Member',
    proxy: {
        type: 'rest',
        url: 'http://localhost:8888/rest/memberapi/members' ,
        reader: {
            type: 'json',
            root: 'data'
        },
        writer: {
            type: 'json'
        }
    },
    listeners: {
        write: function(store, operation){
            var record = operation.getRecords()[0],
                name = Ext.String.capitalize(operation.action),
                verb;


            if (name == 'Destroy' ) {
                record = operation.records[0];
                verb = 'Destroyed';
            } else {
                verb = name + 'd';
            }
            Ext.example.msg(name, Ext.String.format( "{0} member: {1}", verb, record.getId()));

        }
    }
});

看法:

Ext.define('MyLodge.view.content.MemberGrid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.membergrid',

    initComponent: function(){

        var store = Ext.create('MyLodge.store.Members' );

        Ext.apply( this, {
            height: this.height,
            store: store,
            stripeRows: true,
            columnLines: true,
            columns: [{
                id       : 'name',
                text   : 'Name',
                flex: 1,
                sortable : true,
                dataIndex: 'name'
            },{
                text   : 'E-Mail',
                width    : 150,
                sortable : true,
                dataIndex: 'email'
            },{
                text   : 'Href',
                width    : 200,
                sortable : true,
                dataIndex: 'href'
            }],
            dockedItems: [{
                xtype: 'toolbar',
                items: [{
                    text: 'Add',
                    iconCls: 'icon-add',
                    handler: function(){
                        // empty record
                        store.insert(0, new MyLodge.model.Member());
                        rowEditing.startEdit(0, 0);
                    }
                }, '-', {
                    itemId: 'delete',
                    text: 'Delete',
                    iconCls: 'icon-delete',
                    disabled: true,
                    handler: function(){
                        var selection = grid.getView().getSelectionModel().getSelection()[0];
                        if (selection) {
                            store.remove(selection);
                        }
                    }
                }]
            }]
        });

        this.callParent(arguments);
    }
});

但我不确定将代码放在哪里来控制网格行选择并启用删除按钮:

grid.getSelectionModel().on('selectionchange', function(selModel, selections){
    grid.down('#delete').setDisabled(selections.length === 0);
});

此外,当我按下添加按钮时,我收到以下错误:

Uncaught TypeError: Object [object Object] has no method 'insert'.

任何帮助,将不胜感激。

4

2 回答 2

1

您遇到范围界定问题。基本上,该变量store仅在 initComponent 函数中定义,因此在局部函数范围内。你的处理函数有它自己的范围。它在工具栏按钮的范围内触发。因此,如果您this在处理程序中说,它将指的是按钮。因此,您可以说this.up('panel').store- 这为您提供了对支持网格面板的商店的正确引用。

另一个建议是不要一次实施所有事情。写一点看看有没有用,然后一点一点的添加进去。

于 2013-02-12T22:49:38.093 回答
1

RE:文档示例,我同意这令人沮丧,但没有太多选择。对每个示例进行完全 MVC 样式的实现不仅难以生成,而且可能会使示例在结构中丢失。

RE:您关于“放置”代码以控制网格的位置的问题,我建议在 control() 部分中为网格上的事件设置一个带有侦听器的控制器。这将使您可以将网格触发的事件的处理与视图本身分离。

于 2013-02-13T01:04:52.587 回答