web-dev-qa-db-ja.com

ExtJS 4を使用した動的モデル

ExtJS 3.xではStoreの "fields"プロパティを使用できましたが、ExtJS 4では絶対にモデルを使用する必要があるようです。それは問題ありませんが、私の場合、それは静的モデルではなく、その場でフィールドを定義し、時にはそれらを変更する必要があります。

モデルを再作成することはできますが、既存のモデルを変更したり、削除したりすることはできないため、別の名前を使用する必要があります。同じ名前のExt.regModelを使用しようとすると、ExtJSがクラッシュします。

ご協力いただきありがとうございます!

28
TigrouMeow

4.1更新:

更新として... 4.1では、モデルのプロトタイプフィールドを定義するために使用できる静的メソッドsetFieldsが追加されました。コントローラのinitメソッドでうまく機能します。

これを行ったとき、モデルクラスでいくつかの静的フィールドを定義し、さらに動的に設定する必要がありました。残念ながら、新しいsetFieldsメソッドはすべてのフィールドを引数で置き換えますが、それでも十分に簡単に処理できました。

この例では、モデルとストアがコントローラーのmodel配列とstore配列に含まれているMVCパターンを使用しています(以下で使用する便利なゲッターを提供しています)。

Ext.define('ST.controller.Main', {
    extend: 'Ext.app.Controller',

    models: ['User', 'Reference'],

    stores: ['CurrentUser', 'PermissionRef'],

    views: ['MainPanel'],

    init: function() {
        var me = this;

        me.getPermissionRefStore().on('load', function(store, records) {
            var model = me.getUserModel();
                // this returns the static fields already defined 
                // in my User model class
                fields = model.prototype.fields.getRange();

            // add the permission options (dynamic fields) to the static fields
            Ext.each(records, function(permission) {
                fields.Push({name: permission.get('name'), type: 'bool'});
            });

            // 4.1 method to update the User model fields
            model.setFields(fields);

            // now load the current user (it will use the updated model)
            me.getCurrentUserStore().load();

        });

    }

});

UserモデルとCurrentUserストアは通常の非動的モデルとまったく同じように作成され、ストアはそれぞれのコントローラー配列に含まれ、含まれます。「ユーザー」モデルには動的フィールドがありません。上記のように追加されます。

20
Geronimo

私もその問題に入りました。サーバーからメタデータをフェッチし、モデルとストアをこのメタデータに適合させるサービスを担当しています。

したがって、空のモデルを定義し、このモデルを使用するようにストアを構成しました。

メタデータが処理されたら、次のようにモデルのプロトタイプに新規/追加フィールドを追加します(metaDataStoreはメタデータを含むストア、モデルはモデルマネージャーから取得できるモデルです)。

var fields = [];
metaDataStore.each(function(item) {
    fields.Push(Ext.create('Ext.data.Field', {
        name: item.get('field')
    }));
});
model.prototype.fields.removeAll();
model.prototype.fields.addAll(fields);

次に、このモデルを使用してストアでloadを呼び出すか、新しいモデルインスタンスを作成すると、新しいフィールドが正しく処理されます。

17
frow

これは非常に単純な例です。通常のExt.data.Storeを使用するだけで、モデルの代わりにfieldsプロパティを指定します。

// you can specify a simple string ('totally')
// or an object with an Ext.data.Field ('dynamic')
var fields = ['totally', {name : 'dynamic', type : 'string'}];
var newStore = new MyApp.store.Object({
  fields : fields
  // other options like proxy, autoLoad...
});

モデルプロパティを指定しないでください。フィールドプロパティをオーバーライドするようです。

また、既存のグリッドの列とコンテンツを動的に変更したいと思いました。

// reconfigure the grid to use the new store and other columns
var newColumns = [
  {header: 'Totally', dataIndex: 'totally'},
  {header: 'Dynamic', dataIndex: 'dynamic'}
];
myGrid.reconfigure(newStore, newColumns);

Ext.data.Store の "fields"プロパティに関するExt JS 4のドキュメントから:

これは、モデル構成を指定する代わりに使用できます。フィールドは、Ext.data.Field構成オブジェクトのセットである必要があります。ストアは、これらのフィールドを持つExt.data.Modelを自動的に作成します。一般に、この構成オプションは回避する必要があります。これは、下位互換性のために存在しています。特定のidプロパティや関連付けの指定など、より複雑なものについては、Ext.data.Modelを定義し、モデル構成に指定する必要があります。

なので注意してください-Senchaは将来的にそれを削除するかもしれません。

3
user324242