Extjs 4组合框的默认值

31
我正在将我的应用程序从ExtJs 3迁移到4版本。 在我的formPanel中有几个下拉框,以前我使用了hiddenName和所有stuff来提交valueField而不是displayField。
所有的适应工作都很好(value field被提交了),但是在页面加载后我无法设置组合框的默认值,它们显示为空。 以前,我只需在config中指定'value'参数即可做到这一点。 有什么想法如何解决这个问题吗?
我的代码 - 模型和存储:
Ext.define('idNamePair', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'id', type: 'string'},
        {name: 'name',  type: 'string'}
    ]
});

var dirValuesStore = new Ext.data.Store({
    model: 'idNamePair',
    proxy: {
        type: 'ajax',
        url: '../filtervalues.json',
        reader: {
            type: 'json',
            root: 'dir'
        }
    },
    autoLoad: true
});

组合配置:

{
    triggerAction: 'all',
    id: 'dir_id',
    fieldLabel: 'Direction',
    queryMode: 'local',
    editable: false,
    xtype: 'combo',
    store : dirValuesStore,
    displayField:'name',
    valueField:'id',
    value: 'all',
    width: 250,
    forceSelection:true
}

请提供一些示例代码,以便我们查看问题并找到可能的解决方案。 - onteria_
问题非常明确。即使我不知道答案,也不需要编写代码,因为我仍然卡在3.x上。 - sra
我猜这又是一个关于异步加载存储和组合框的问题,因为如果在组合框内定义存储 - 它就可以正常工作。 - BlackLine
我也注意到了同样的问题。 - Marko
9个回答

23

我遇到了同样的问题,据我所知这与selectlist在项目添加到存储之前进行渲染有关。我尝试了上面提到的回调方法,但没有成功(猜测它应该是在selectlist而不是存储上的回调)。

在添加项目到存储后,我添加了这一行代码,它可以正常工作:

Ext.getCmp('selectList').setValue(store.getAt('0').get('id'));

13

loading: true添加到您的存储配置中,即可修复此问题。 autoLoad: trueforceSelection: true似乎存在问题。 这个小技巧将使您的下拉框相信存储正在加载,即使尚未触发加载函数。


@BlackLine 很好!我会投两票!这个解决方案简单而有效。 - user1636522
1
对于那些好奇为什么这个方法有效的人,原因是Store constructor通过将autoLoad的加载调用延迟1毫秒(请参见构造函数代码的末尾)来实现。因此,在调用组合框setValue方法之后,存储的loading属性才被设置为true,因此组合框存储认为存储已加载但值无效(因为存储实际上为空)。 - rixo
1
我建议通过覆盖 Ext.data.Store#constructor 来系统范围内解决这个问题,如果 autoLoad 也为 true,则将 loading 设置为 true。例如:Ext.define(null, { override: 'Ext.data.Store', constructor: function() { this.callParent(arguments); if (this.autoLoad) { this.loading = true; } } }); - rixo

12

最好的方法是监听 afterrender 事件,然后在回调函数中设置默认值。

参考以下代码:

new Ext.form.field.ComboBox({
    //This is our default value in the combobox config
    defaultValue: 0,
    listeners: {
        //This event will fire when combobox rendered completely
        afterrender: function() {
           //So now we are going to set the combobox value here.
           //I just simply used my default value in the combobox definition but it's possible to query from combobox store also.
           //For example: store.getAt('0').get('id'); according to Brik's answer.
           this.setValue(this.defaultValue);    
        }
    }
});

6
我注意到你的组合框配置中有queryMode: 'local'。该值适用于当数据存储在数组中时使用。但是你的模型正在使用AJAX代理。这可能会让Ext混淆,无法找到你尝试设置的默认值。尝试删除queryMode,以便它默认为'remote'的值(或明确设置它)。
更新:我在发布上述内容后立即将自己的应用程序从Ext3迁移到4,遇到了完全相同的问题。我确定queryMode是其中的一部分,但主要问题是组合框在呈现时还没有所需的数据。设置value可以给它一个值,但是数据存储中还没有匹配它的内容,因此该字段显示为空白。我发现autoLoad属性也可以指定在加载数据时使用的回调函数。以下是你可以执行的操作:
store: new Ext.data.Store({
    model: 'MyModel',
    autoLoad: {
        scope: this,
        callback: function() {
            var comboBox = Ext.getCmp("MyComboBoxId");
            var store = comboBox.store;

            // set the value of the comboBox here
            comboBox.setValue(blahBlahBlah);
        }
    }
    ...
})

4

你可以直接将逻辑放在回调函数中,或者设置一个函数来处理所有的存储。

var store1 = Ext.create('Ext.data.Store', {
    ...
    autoLoad: {
        callback: initData 
    }
});

var store2 = Ext.create('Ext.data.Store', {
    ...
    autoLoad: {
        callback: initData 
    }
});

var myComboStores = ['store1', 'store2']

function initData() {
    var loaded = true;
    Ext.each(myComboStores, function(storeId) {
        var store = Ext.StoreManager.lookup(storeId);
        if (store.isLoading()) {
            loaded = false;
        }
    }
    if(loaded) {
        // do stuff with the data
    }
}

对于那些阅读本文的人,你的“combo”对象的value配置/属性应该设置为某个值,这样组合框就会得到一个初始值。您已经完成了这个步骤。存储器中还需要存在值“all”,才能将其设置为默认值。

value: 'all'

另外,为valueField属性设置一个值是一个好习惯,您已经做到了。如果不这样做,当调用combo.getValue()时,选择监听器将无法获得正确的值。


1
我敢打赌这与你异步加载下拉框的时间以及设置下拉框值的时间有关。为了解决这个问题,只需按照以下步骤操作:
Ext.define('idNamePair', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'id', type: 'string'},
        {name: 'name',  type: 'string'}
    ]
});

var dirValuesStore = new Ext.data.Store({
    model: 'idNamePair',
    proxy: {
        type: 'ajax',
        url: '../filtervalues.json',
        reader: {
            type: 'json',
            root: 'dir'
        }
    },
    autoLoad: false // set autoloading to false
});

存储的自动加载已关闭。现在,在使用您起始帖子中的代码将ComboBox放置在某个位置之后,您只需手动加载存储: dirValuesStore.load();

这可能是在某个组件的initComponent()中的配置Ext.apply(this, {items: [..., {xtype: 'combo', ...}, ...]})之后。


1

尝试这段代码:

var combo = new Ext.form.field.ComboBox({
    initialValue : something,
    listeners: {
        afterrender: function(t,o ) {
           t.value = t.initialValue;    
        }
    }
}) 

1

在配置中指定'value'参数是设置组合框默认值的正确方法。

在您的示例中,只需设置forceSelection:false,它就可以正常工作。

如果您想设置forceSelection:true,请确保从存储返回的数据包含一个项目,其值等于您的默认值(在此情况下为“all”)。否则,默认情况下将为空文本。为了更清楚,请用以下内容替换您的dirValuesStore定义:

    var dirValuesStore = Ext.create('Ext.data.Store', {
        fields: ['id', 'name'],
        data: [
            {id: 'all', name: 'All'},
            {id: '1', name: 'Name 1'},
            {id: '2', name: 'Name 2'},
            {id: '3', name: 'Name 3'},
            {id: '4', name: 'Name 4'}
        ]
    })

你会看到它有效!

1
在Extjs 5.0.1中,这应该是有效的,在配置combo中:
...
editable: false,
forceSelection: true,
emptyText: '',

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