ExtJS 4动态模型

29

在 ExtJS 3.x 中,我可以使用 Store 的 "fields" 属性,但是在 ExtJS 4 中似乎必须绝对使用 Model。这没关系,但在我的情况下,它不是一个静态的 Model,我需要在运行时定义字段,并且有时需要更改它们。

我可以重新创建一个 Model,但我需要使用不同的名称,因为显然无法修改现有的 Model,也不能删除它。如果我尝试使用相同的名称进行 Ext.regModel,ExtJS 将崩溃。

感谢您的帮助!

3个回答

20

4.1 更新:

更新内容是,现在在 4.1 版本中,有一个名为 setFields 的静态方法,可用于定义模型原型字段。它可很好地运用于控制器的 init 方法。

当我这么做时,我希望在模型类中定义一些静态字段,然后再动态设置一些字段。不幸的是,新的 setFields 方法会用参数替换所有字段,但处理起来很容易。

此示例使用 MVC 模式,其中我的模型和存储包含在控制器的 modelstore 数组中(下面使用这些方便的 getter):

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存储器的方式与普通的非动态模型和存储器完全相同,并将它们包含在各自的控制器数组中,'User'模型仅缺少上述添加的动态字段。


为什么不直接将新字段添加到“fields”“MixedCollection”中? “setFields”方法是否需要进行任何必要的处理? 我的意思是除了创建“Field”实例之外,在您的情况下。 - rixo

17

我也遇到了这个问题。我有一个负责从服务器获取元数据并将模型和存储适应到此元数据的服务。

因此,我定义了一个空模型并配置存储以使用此模型。

当处理元数据时,我像这样将新/附加字段添加到模型的原型中(metaDataStore是包含元数据的存储,model是可以从模型管理器获取的模型):

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方法或创建新的模型实例时,新字段会被正确处理。


3
这是一个非常简单的例子。只需使用普通的Ext.data.Store,而不是模型,指定字段属性即可:
// 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 JS 4关于Ext.data.Store的“fields”属性的文档中可以看到:

可以使用此选项代替指定模型配置。字段应该是一组Ext.data.Field配置对象。存储将自动使用这些字段创建一个Ext.data.Model。通常情况下,应避免使用此配置选项,它存在于向后兼容性的目的。对于任何更复杂的内容,例如指定特定的id属性或关联,应该定义并指定Ext.data.Model的模型配置。

所以要小心-Sencha可能会在未来删除它。

小心 - 如果您在忽略模型的情况下设置存储字段,并且您有自定义的Id字段,则会失败。 您的存储记录将设置其Id,但无法通过getId()返回Id,因为它们不知道自定义Id的存在。 不确定这是否是错误,但我已经报告了 http://www.sencha.com/forum/showthread.php?280160-model.getId()-with-custom-IdProperty-fails-when-and-store-fields-set-via-metaData&p=1024289&viewfull=1#post1024289 - Dave
这是对我有效的... 必须摒弃“模型”,而是硬编码进行配置。 - PedroMorgan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接