2011-05-11 33 views
24

Estoy migrando mi aplicación de la versión 3 a 4 de ExtJs. Tengo varios cuadros combinados en mi formPanel, y anteriormente he usado hiddenName y todo eso stuff para enviar valueField en lugar de displayField.Extjs 4 Valor predeterminado de combobox

Todas mis adaptaciones funcionan bien (el campo de valor IS se envía), pero no puedo establecer los valores predeterminados para los cuadros combinados, se muestran 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 de la 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 
}); 

Combo config:

{ 
    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 
} 
+0

por favor, puesto algunos ejemplos de código para que tomemos un vistazo a la emisión y una posible solución. –

+0

La pregunta es precisa. No se requiere código, incluso si no sé la respuesta porque todavía estoy atrapado en 3.x – sra

+0

Supongo que es una vez más una cuestión de carga asincrónica de tienda y combo, porque si la tienda se define dentro de combo, funciona bien . – BlackLine

Respuesta

4

me di cuenta de su configuración Combo tiene queryMode: 'local'. Ese valor está destinado a cuando sus datos se almacenan localmente en una matriz. Pero su modelo está usando un proxy AJAX. ¿Podría ser que esto confunde a Ext, por lo que no puede encontrar el valor predeterminado que intentas establecer? Intente eliminar queryMode para que adopte 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 me encontré con exactamente el mismo problema . Estoy seguro de que queryMode es parte de esto, pero el problema principal es que el cuadro combinado no tiene los datos necesarios todavía en el momento en que se procesa. El valor value le da un valor pero todavía no hay nada en el data store que lo combine, por lo que el campo aparece en blanco. Descubrí que la propiedad autoLoad también puede especificar una función de devolución de llamada que se utilizará cuando se carguen los datos. Esto es lo que se podía 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); 
     } 
    } 
    ... 
}) 
17

tuve el mismo problema, que yo sepa, tiene que ver con la representación selectlist antes de que los elementos se agregan 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 la tienda).

que añade esta línea después de añadir elementos al almacén y trabaja muy bien:

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

Gracias, tienes toda la razón –

0

apuesto a que esto tiene que ver con el tiempo que (de forma asíncrona) cargar el cuadro combinado, y el tiempo que establezca el valor de la caja combinada. Para solucionar este problema, simplemente haga lo siguiente:

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 ha colocado su ComboBox en un lugar determinado - usando el código en su publicación inicial - simplemente carga la tienda manualmente: dirValuesStore.load();.

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

0

probar este código:

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

Usted puede poner la lógica directamente en la devolución de llamada, o la creación de 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 lectura, el valor config/propiedad en su 'combo' objeto debe establecerse en algún valor para que el cuadro combinado obtenga un valor inicial. Ya has hecho esto. El valor 'todo' también debe estar en su tienda antes de que lo configure como el predeterminado.

value: 'all' 

Además, es una buena práctica para establecer un valor para el campo de Valor config, que usted ha hecho ya. Si no lo hace, el oyente de selección no obtendrá el valor correcto al llamar a combo.getValue().

4

La mejor manera de hacerlo es escuchar el evento afterrender 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);  
     } 
    } 
}); 
10

Adición loading: true a su configuración tienda lo arreglará. Parece que hay un problema con autoLoad: true y forceSelection: true. Este pequeño hack hará que tu combobox crea que la tienda se está cargando aunque la función de carga aún no se haya activado.

+0

@BlackLine ¡Agradable! ¡Yo votaría dos veces! Esta solución es simple y efectiva. – leaf

+1

Para aquellos que sienten curiosidad acerca de por qué esto funciona, es porque [el constructor de la tienda] (http://docs.sencha.com/extjs/4.2.1/source/Store.html#Ext-data-Store-method- constructor), difiere la llamada de carga 'autoLoad' en 1 ms (ver al final del código del constructor). Por lo tanto, la propiedad 'loading' de la tienda se establece en' true' solo después de llamar al método combo box 'setValue', por lo que la tienda combinada piensa que la tienda está cargada y el valor no es válido (porque la tienda está en hecho vacío). – rixo

+1

Recomiendo que se solucione todo el sistema anulando 'Ext.data.Store # constructor' para establecer' loading' en 'true' si' autoLoad' también es 'true'. P.ej. 'Ext.definir (null, { \t override: 'Ext.data.Store', \t constructor: function() { \t \t this.callParent (argumentos); \t \t si (this.autoLoad) { \t \t \t this.loading = true; \t \t} \t} }); ' – rixo

0

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

En su ejemplo, simplemente configure forceSelection:false, funcionará bien.

En caso de que desee establecer forceSelection:true, debe asegurarse de que los datos devueltos desde su tienda contengan un artículo que tenga el valor igual a su valor predeterminado ('todo' en este caso). De lo contrario, será un texto vacío por defecto. Para ser más claro, por favor reemplazar su definición dirValuesStore 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'} 
     ] 
    }) 

Usted verá que funciona!

0

En Extjs 5.0.1 esto debería funcionar, en combinación config:

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