2

ExtJS に関する Sencha のドキュメントに非常に困惑しています。ドキュメントは、アプリケーションのクラスとソース コードに適した構造の重要性を強調し、説明する入門ガイドから始まります。ただし、提供されている例は、入門ガイドで定められたすべての規則を破っています。コードを適切なモデル、ストア、ビューなどのクラス ファイルに分割する代わりに、サンプル ソース コードを含む 1 つのファイルとしてサンプルが提供されます。

ポータルの例 ( http://docs.sencha.com/ext-js/4-1/#!/example/portal/portal.html ) に従うことから始めました。これは私が作成したいアプリケーションの一種だからです。ポータルの例を拡張し、グリッドを表示して 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-そして、それはあなたのグリッドパネルを裏打ちするストアへの正しい参照をあなたに与えます.

もう 1 つのアドバイスは、一度にすべてを実装しないことです。少し書き込んで動作するかどうかを確認してから、少しずつ追加します。

于 2013-02-12T22:49:38.093 に答える
1

RE: ドキュメントの例。イライラすることには同意しますが、多くのオプションはありません。各例を完全に MVC スタイルで実装すると、作成が面倒になるだけでなく、例の要点が構造内で失われてしまう可能性があります。

RE: グリッドを制御するコードをどこに「配置」するかについての質問です。control() セクションでグリッド上のイベントのリスナーを使用してコントローラーを設定することをお勧めします。これにより、グリッドによって発生したイベントの処理をビュー自体から切り離すことができます。

于 2013-02-13T01:04:52.587 に答える