2011-05-11 4 views
24

Sto migrando la mia applicazione dalla versione 3 - 4 di ExtJs. Ho diversi combobox sul mio formPanel, e in precedenza ho usato hiddenName e tutto questo stuff per inviare valueField invece di displayField.Valore predefinito combobox Extjs 4

Tutti i miei adattamenti funzionano correttamente (campo di valori che viene inviato), ma non posso impostare i valori predefiniti per le caselle combinate, sono visualizzati come vuoti dopo il caricamento della pagina. Precedentemente, l'ho fatto solo specificando il parametro 'value' in config. C'è qualche idea su come risolverlo?

Il mio codice - modello e Store:

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

prega di inviare alcuni esempi di codice per noi di prendere uno sguardo al problema e una possibile soluzione. –

+0

La domanda è precisa. Non è richiesto alcun codice anche se non conosco la risposta perché sono ancora bloccato in 3.x – sra

+0

Immagino sia di nuovo una questione di caricamento asincrono di store e combo, perché se store è definito all'interno di combo - funziona bene . – BlackLine

risposta

4

ho notato il tuo config Combo ha queryMode: 'local'. Questo valore è inteso per quando i dati sono archiviati localmente in un array. Ma il tuo modello sta usando un proxy AJAX. Potrebbe essere che questo confonda Ext in modo che non possa trovare il valore predefinito che stai cercando di impostare? Prova a rimuovere queryMode in modo predefinito per il valore di "remoto" (o impostarlo in modo esplicito)

AGGIORNAMENTO: Stavo migrando la mia app da Ext3 a 4 subito dopo aver postato quanto sopra, e mi sono imbattuto nello stesso identico problema . Sono sicuro che queryMode è parte di esso, ma il problema principale è che la casella combinata non ha ancora i dati necessari al momento del rendering. L'impostazione di value gli fornisce un valore ma non c'è ancora nulla nell'archivio dati con cui associarlo, quindi il campo appare vuoto. Ho scoperto che la proprietà autoLoad può anche specificare una funzione di callback da utilizzare quando i dati vengono caricati. Ecco cosa si potrebbe fare:

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

ho avuto lo stesso problema, ha afaik a che fare con il rendering SelectList prima che gli elementi vengono aggiunti al negozio. Ho provato il metodo di richiamata di cui sopra senza fortuna (suppongo che dovrebbe essere una richiamata sulla selectlist piuttosto che sul negozio).

ho aggiunto questa linea dopo l'aggiunta di elementi all'archivio e funziona benissimo:

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

Grazie, hai perfettamente ragione –

0

Scommetto che questo ha a che fare con il tempo (in modo asincrono) caricare la casella combinata, e il tempo si imposta il valore della casella combinata. Per ovviare a questo problema, esegui semplicemente questa operazione:

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

L'autoloading del negozio è disattivato. Ora, dopo il hai collocato il tuo ComboBox in un determinato luogo, utilizzando il codice nel tuo post di partenza, semplicemente carichi lo store manualmente: dirValuesStore.load();.

Questo è probabilmente dopo la configurazione Ext.apply(this, {items: [..., {xtype: 'combo', ...}, ...]}) in alcuni componenti initComponent().

0

provare questo codice:

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

è possibile mettere la logica direttamente nella richiamata, o impostare una funzione per gestire tutti i negozi.

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

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

per chi legge, il valore config/proprietà sulla vostra 'combo' oggetto dovrebbe essere impostato su un valore in modo che la casella combinata abbia un valore iniziale. L'hai già fatto. Il valore 'all' deve anche essere nel tuo negozio prima che lo imposti come predefinito.

value: 'all' 

Inoltre, è buona norma impostare un valore per il ValueField config, che hai fatto già. In caso contrario, il listener selezionato non otterrà il valore corretto quando chiama combo.getValue().

4

Il modo migliore per farlo è ascoltare l'evento afterrender e quindi impostare il valore predefinito nella funzione di callback.

Vedi questo codice:

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

Aggiunta loading: true al tuo negozio config lo risolverà. Sembra esserci un problema con autoLoad: true e forceSelection: true. Questo piccolo trucco renderà la tua casella combinata credibile che il negozio stia caricando anche se la funzione di caricamento non è stata ancora attivata.

+0

@BlackLine Nice! Voterei due volte! Questa soluzione è semplice ed efficace. – leaf

+1

Per coloro che sono curiosi del perché questo funziona, è perché il [Store constructor] (http://docs.sencha.com/extjs/4.2.1/source/Store.html#Ext-data-Store-method- costruttore), rimanda la chiamata di carico di 'autoLoad' di 1ms (vedere alla fine del codice costruttore). Quindi, la proprietà 'loading' del negozio è impostata su' true' solo dopo che è stato chiamato il metodo 'setValue' della casella combinata, e quindi l'archivio combinato pensa che lo store sia caricato e il valore non sia valido (perché lo store è in fatto vuoto). – rixo

+1

Suggerirei di correggere l'intero sistema sostituendo il 'Ext.data.Store # constructor' per impostare' loading' su 'true' se' autoLoad' è anche 'true'. Per esempio. 'Est.define (null, { \t Override: 'Ext.data.Store', \t costruttore: function() { \t \t this.callParent (argomenti); \t \t se (this.autoLoad) { \t \t \t this.loading = true; \t \t} \t} }); ' – rixo

0

Specificare il parametro "valore" nella configurazione è un modo corretto per impostare i valori predefiniti per le caselle combinate.

Nell'esempio, è sufficiente impostare forceSelection:false, funzionerà correttamente.

Nel caso in cui si desideri impostare forceSelection:true, è necessario assicurarsi che i dati restituiti dal proprio archivio contengano un articolo che ha il valore uguale al valore predefinito ("tutto" in questo caso). In caso contrario, sarà un testo vuoto per impostazione predefinita. Per essere più chiaro, si prega di sostituire la definizione dirValuesStore da questo:

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

Vedrete funziona!

0

In ExtJS 5.0.1 questo dovrebbe funzionare, in combo config:

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