Valor predeterminado del cuadro combinado de Extjs 4

30

Estoy migrando mi aplicación de la versión ExtJs 3 a 4. Tengo varios cuadros combinados en mi formPanel, y anteriormente he usado hiddenName y todas esas cosas para enviar valueField en lugar de displayField.

Toda mi adaptación funciona bien (el campo de valor se está enviando), pero no puedo establecer los valores predeterminados para los cuadros combinados, se muestran como vacíos después de la carga de la página. Anteriormente, lo hice solo especificando el parámetro 'valor' en config. ¿Hay alguna idea de cómo solucionarlo?

Mi código - Modelo y tienda:

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
});

Configuración combinada:

{
    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
}
4
  • Publique un código de muestra para que veamos el problema y una posible solución. 11 de mayo de 2011 a las 13:57
  • La pregunta es precisamente. No se requiere ningún código incluso si no sé la respuesta porque todavía estoy atascado en 3.x
    sra
    11 de mayo de 2011 a las 14:35
  • Supongo que es nuevamente una cuestión de carga asincrónica de store y combo, porque si store se define dentro de combo, funciona bien. 12 de mayo de 2011 y 11:10
  • También noté el mismo problema.
    Marko
    16/07/11 a las 11:44
23

Tuve el mismo problema, afaik tiene que ver con la representación de la lista de selección antes de que los elementos se agreguen a la tienda. Probé el método de devolución de llamada mencionado anteriormente sin suerte (supongo que tendría que ser una devolución de llamada en la lista de selección en lugar de en la tienda).

Agregué esta línea después de agregar artículos a la tienda y funciona bien:

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

Agregarlo loading: truea la configuración de su tienda lo solucionará. Parece haber un problema con autoLoad: truey forceSelection: true. Este pequeño truco hará que su cuadro combinado crea que la tienda se está cargando incluso si la función de carga aún no se ha activado.

3
  • @BlackLine ¡Niza! ¡Votaría dos veces! Esta solución es sencilla y eficaz.
    leaf
    24 de enero de 2013 a las 8:18
  • 1
    Para aquellos que tienen curiosidad acerca de por qué funciona esto, es porque el constructor de la tienda difiere la autoLoadllamada de carga de 1ms (ver al final del código del constructor). Por lo tanto, la loadingpropiedad de la tienda se establece en truesolo después de setValueque se llama al método del cuadro combinado , por lo que la tienda combinada cree que la tienda está cargada y el valor no es válido (porque la tienda está vacía).
    rixo
    29 de septiembre de 2013 a las 12:44
  • 1
    Me gustaría recomendar la fijación de que todo el sistema reemplazando Ext.data.Store#constructoral conjunto loadingde truesi autoLoades también true. P.ej Ext.define(null, { override: 'Ext.data.Store', constructor: function() { this.callParent(arguments); if (this.autoLoad) { this.loading = true; } } });
    rixo
    29 de septiembre de 2013 a las 12:45
11

La mejor manera de hacer esto es escuchar el afterrenderevento y luego establecer el valor predeterminado en la función de devolución de llamada.

Ver este código:

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);    
        }
    }
});
5

Me di cuenta de que su configuración de Combo tiene queryMode: 'local'. Ese valor está diseñado para cuando sus datos se almacenan localmente en una matriz. Pero su modelo está usando un proxy AJAX. ¿Podría ser que esto confunda a Ext por lo que no puede encontrar el valor predeterminado que está tratando de establecer? Intente eliminarlo queryModepara que tenga el valor predeterminado de 'remoto' (o configúrelo explícitamente).

ACTUALIZACIÓN: Estaba migrando mi propia aplicación de Ext3 a 4 justo después de publicar lo anterior, y encontré exactamente el mismo problema. Estoy seguro de que queryModees parte de ello, pero el problema principal es que el cuadro combinado aún no tiene los datos necesarios en el momento en que se procesa. La configuración valuele da un valor, pero aún no hay nada en el almacén de datos con lo que pueda coincidir, por lo que el campo aparece en blanco. Descubrí que la autoLoadpropiedad también puede especificar una función de devolución de llamada que se utilizará cuando se carguen los datos. Esto es lo que puedes hacer:

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

Puede poner la lógica directamente en la devolución de llamada o configurar una función para manejar todas las tiendas.

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
    }
}

=====================

Para aquellos que leen, el valor config / property en su objeto 'combo' debe establecerse en algún valor para que el cuadro combinado obtenga un valor inicial. Ya hiciste esto. El valor 'todos' también debe estar en su tienda antes de establecerlo como predeterminado.

value: 'all'

Además, es una buena práctica establecer un valor para la configuración valueField , que ya ha hecho. Si no lo hace, el oyente seleccionado no obtendrá el valor correcto al llamar a combo.getValue ().

1

Apuesto a que esto tiene que ver con el tiempo que usted (asincrónicamente) carga el cuadro combinado y el tiempo que establece el valor del cuadro combinado. Para superar este problema, simplemente haga esto:

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
});

La carga automática de la tienda está desactivada. Ahora, después de haber hecho su ComboBox en un cierto lugar - utilizando el código en su puesto de partida - sólo tiene que cargar manualmente la tienda: dirValuesStore.load();.

Eso es probablemente después de la configuración Ext.apply(this, {items: [..., {xtype: 'combo', ...}, ...]})en algunos componentes initComponent().

1

Prueba este código:

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

Especificar el parámetro 'valor' en la configuración es una forma correcta de establecer los valores predeterminados para los cuadros combinados.

En su ejemplo, simplemente configúrelo forceSelection:false, funcionará bien.

En caso de que desee configurar forceSelection:true, debe asegurarse de que los datos devueltos de su tienda contengan un artículo que tenga el valor igual a su valor predeterminado ('todos' en este caso). De lo contrario, será un texto vacío por defecto. Para ser más claro, reemplace su dirValuesStoredefinición por esto:

    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'}
        ]
    })

¡Verás que funciona!

1

En Extjs 5.0.1 esto debería funcionar, en el combo de configuración:

...
editable: false,
forceSelection: true,
emptyText: '',