Ext.form.field.ComboBox 梳理出所有数据源配置方式

Ext.form.field.ComboBox 运行时只有一种真正的数据源——Ext.data.Store。数组、Store 配置、Store ID、ViewModel 数据等,最终都会被归一化为 Store。

一、所有数据源配置方式

配置方式示例最终处理
Store 实例 store: myStore 直接绑定该 Store
Store ID store: 'cityStore' 通过 Ext.data.StoreManager 查找
Store 配置对象 store: { fields, data, proxy } Ext.Factory.store() 创建 Store
自定义 Store 类型 store: { type: 'citystore' } 根据 alias 创建自定义 Store
一维数组 store: ['无', '轻微', '严重'] 创建 ArrayStore,字段为 field1
二维数组 store: [['0','无'], ['1','轻微']] 创建 ArrayStore,字段为 field1field2
对象数组 store: [{id: 1, name: '北京'}] 包装成普通 Store
HTML <select> transform: 'selectId' 提取 option,生成二维数组
ViewModel 动态绑定 bind: { store: '{options}' } 数据到达后调用 setStore()
运行时切换 combo.setStore(source) 重新走 Store 归一化与绑定流程

原生说明见 [ComboBox.js (line 268)](/D:/WWW/nestjs/public/ext/classic/classic/src/form/field/ComboBox.js:268),

真正的归一化逻辑在 [StoreManager.js (line 82)](/D:/WWW/nestjs/public/ext/packages/core/src/data/StoreManager.js:82)。

二、数组数据的字段映射规则

一维数组

store: ['无锈蚀', '轻微锈蚀', '重度锈蚀']

会转换成:

[
    ['无锈蚀'],
    ['轻微锈蚀'],
    ['重度锈蚀']
]

自动创建字段:

field1

ComboBox 随后自动调整为:

displayField: 'field1'
valueField: 'field1'
queryMode: 'local'

二维数组

store: [
    ['0', '无锈蚀'],
    ['1', '轻微锈蚀']
]

自动创建:

field1 = 实际值
field2 = 显示文本

ComboBox 自动调整为:

valueField: 'field1'
displayField: 'field2'
queryMode: 'local'

相关代码见 [ComboBox.js (line 1189)](/D:/WWW/nestjs/public/ext/classic/classic/src/form/field/ComboBox.js:1189) 和 [StoreManager.js (line 98)](/D:/WWW/nestjs/public/ext/packages/core/src/data/StoreManager.js:98)。

对象数组

store: [
    { code: '0', name: '无锈蚀' },
    { code: '1', name: '轻微锈蚀' }
],
valueField: 'code',
displayField: 'name'

对象数组不会像一维、二维数组那样自动推导 field1/field2 映射,因此应明确配置 displayFieldvalueField

如果不配置,ComboBox 默认:

displayField: 'text'
valueField: displayField

也就是说对象至少要包含 text,否则候选项可能渲染为空。

三、Store 配置对象

这是字段明确、生命周期最稳定的写法:

store: {
    fields: ['code', 'name'],
    data: [
        { code: '0', name: '无锈蚀' },
        { code: '1', name: '轻微锈蚀' }
    ]
},
valueField: 'code',
displayField: 'name',
queryMode: 'local'

也可以配置远程 Store:

store: {
    fields: ['code', 'name'],
    proxy: {
        type: 'ajax',
        url: '/reader',
        reader: {
            type: 'json',
            rootProperty: 'data'
        }
    }
},
valueField: 'code',
displayField: 'name',
queryMode: 'remote'

没有显式 type 的 Store 配置,默认创建普通 Ext.data.Store,见 [AbstractStore.js (line 20)](/D:/WWW/nestjs/public/ext/packages/core/src/data/AbstractStore.js:20)。

四、ViewModel 数据源

正确的 Store 绑定写法是:

bind: {
    store: '{jsqxs}'
}

不能写成:

bind: '{jsqxs}'

因为 ComboBox 的 defaultBindPropertyvalue;后一种写法绑定的是当前值,不是候选数据源。绑定处理见 [Bindable.js (line 271)](/D:/WWW/nestjs/public/ext/packages/core/src/mixin/Bindable.js:271)。

ViewModel 中可以放:

普通数组

data: {
    jsqxs: ['无锈蚀', '轻微锈蚀']
}

数组到达 ComboBox 后,会通过 setStore() 转成 ArrayStore

Store 实例

data: {
    jsqxsStore: Ext.create('Ext.data.Store', {
        fields: ['code', 'name'],
        data: [...]
    })
}

ViewModel stores

stores: {
    jsqxs: {
        fields: ['code', 'name'],
        data: [...]
    }
}

使用:

bind: {
    store: '{jsqxs}'
}

还支持动态 Store 配置、过滤条件绑定和 ChainedStore,见 [ViewModel.js (line 903)](/D:/WWW/nestjs/public/ext/packages/core/src/app/ViewModel.js:903)。

五、HTML <select> 转换

ComboBox 可以直接接管已有的 <select>

{
    xtype: 'combo',
    transform: 'mySelect'
}

每个 option 被转换为:

[option.value, option.text]

因此最终仍然属于二维数组 Store。如果同时配置了 store,显式 Store 优先。实现见 [ComboBox.js (line 725)](/D:/WWW/nestjs/public/ext/classic/classic/src/form/field/ComboBox.js:725)。

六、queryMode 不是数据源类型

queryMode 只是 Store 的使用方式:

  • local:在已加载的数据中,按照 displayField 建立本地过滤器。
  • remote:调用 store.load(),默认将用户输入作为 query 参数发送。
  • pageSize > 0:远程查询时启用分页。
  • queryCaching:相同查询是否复用结果。
  • minCharsqueryDelay:控制何时触发查询。

本地查询实现见 [ComboBox.js (line 1594)](/D:/WWW/nestjs/public/ext/classic/classic/src/form/field/ComboBox.js:1594),远程查询见 [ComboBox.js (line 1649)](/D:/WWW/nestjs/public/ext/classic/classic/src/form/field/ComboBox.js:1649)。

beforequeryexpand 中调用 loadData(),本质上是运行时人工填充 Store,不是另一种数据源配置方式。

posted on 2026-08-14 13:45  xsSystem  阅读(3)  评论(0)    收藏  举报