将json数组与组合框绑定

时间:2012-10-13 03:43:52

标签: extjs extjs4 extjs4.1

我从页面获取json数组字符串作为响应。我想用组合框绑定它。

这是成功块,它为我提供了json数组字符串:

json数组字符串如下所示:

messagebox displaying the json array string

请让我知道锄头将它与组合框下拉绑定。

此致

修改

这是我尝试过的最新代码:

Ext.define('Country',{
extend: 'Ext.data.Model',
fields: [
    { name: 'id', type: 'string' },
    { name: 'name', type: 'string' }
]
});

Ext.define('CountryCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.countrycombo',
allowBlank: false,
queryMode: 'local',
valueField: 'id',
displayField: 'name',
store: {
    model: 'Country',
    data: [
        { id: 'China', name: 'China'},
        { id: 'Japan', name: 'Japan'},
        { id: 'Malaysia', name: 'Malaysia'}
    ]
},
listeners: {
    "select": function(obj){  
        Ext.Ajax.request({
            url: '/CellEditing/FormServlet',
            method: 'POST',
            params: {
                data: obj.getValue()
            },
            success: function(obj){
                alert('success');
                alert(obj.responseText);
                console.log(StateCombo.storeStates); //This is undefined hence getting error
                StateCombo.storeStates.loadData(obj.responseText);
            },
            failure: function(obj){
                alert('failure');
            }
        });                 
    }
}
});

var storeStates = Ext.create('Ext.data.Store', {
autoLoad: false,
fields: ['State']
});

Ext.define('State',{
extend: 'Ext.data.Model',
fields: [
    { name: 'id', type: 'int' },
    { name: 'name', type: 'string' }
]
});

Ext.define('StateCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.statecombo',
queryMode: 'local',
valueField: 'State',
displayField: 'State',
store: storeStates
});

这是我尝试的最新版本,但是当我从第一个组合框中选择一些东西时,第二个组合框没有被填充。对此有任何帮助吗?

5 个答案:

答案 0 :(得分:4)

从技术上讲,这段代码可行:

http://jsfiddle.net/sdt6585/wPzPD/29/

Ext.define('Country',{
    extend: 'Ext.data.Model',
    fields: [
        { name: 'id', type: 'string' },
        { name: 'name', type: 'string' }
    ]
});

Ext.define('CountryCombo', {
    extend: 'Ext.form.field.ComboBox',
    alias: 'widget.countrycombo',
    allowBlank: false,
    queryMode: 'local',
    valueField: 'id',
    displayField: 'name',
    store: {
        model: 'Country',
        data: [
            { id: 'China', name: 'China'},
            { id: 'Japan', name: 'Japan'},
            { id: 'Malaysia', name: 'Malaysia'}
        ]
    },
    listeners: {
        "select": function(obj){
            Ext.Ajax.request({
                url: '/CellEditing/FormServlet',
                method: 'POST',
                params: {
                    data: obj.getValue()
                },
                callback: function (response, operation) {
                    //This should be the text string in reponseText, just putting it there since I don't have it
                    response.responseText = '{data: [{state: "State One"}, {state: "State Two"}, {state: "State Three"}]}'
                    //Put this in your success function
                    var data = Ext.JSON.decode(response.responseText).data;
                    storeStates.loadData(data);
                }
            });
        }
    }
});

var storeStates = Ext.create('Ext.data.Store', {
    autoLoad: false,
    fields: ['state']
});

Ext.define('State',{
    extend: 'Ext.data.Model',
    fields: [
        { name: 'id', type: 'int' },
        { name: 'name', type: 'string' }
    ]
});

Ext.define('StateCombo', {
    extend: 'Ext.form.field.ComboBox',
    alias: 'widget.statecombo',
    queryMode: 'local',
    valueField: 'state',
    displayField: 'state',
    store: storeStates
});

Ext.form.Panel.create({
    title: 'Tester',
    renderTo: Ext.getBody(),
    items: [
        CountryCombo.create(),
        StateCombo.create()
    ]
});​

主要变化如下:

  • 你需要在你的ajax调用的成功函数中用Ext.JSON.decode(response.responseText)解码你得到的json字符串
  • 您定义了一个状态模型,但状态存储没有使用它。它可以删除。
  • 除了json字符串之外,你的状态变量大概都是大写的。将其更正为小写。
  • 您对状态组合的引用仅适用于该视图的模板类,而不是它的实例。另外,如果它是一个初始化类,它的store属性就是这样定义的,与你的变量名无关。您可以存储对创建的组合框的引用并调用它的商店属性loadData函数,或者像我一样,只需使用storeStates对商店的引用来加载数据。

虽然技术上有效,但它并不是最优雅的解决方案。您将使用更多可维护的代码来执行此过程。

  1. 定义Country和State的模型(理想情况下不在全局命名空间!!)并为状态存储提供代理以自动解码json响应。
  2. 定义使用模型作为基础的商店
  3. 定义组合框的视图(仅当它们将在其他地方重复使用时)
  4. 将组合框的实例放在某种容器中(使用视图类的Ext.create()或create()函数。
  5. 将侦听器附加到您创建的国家/地区组合的实例,并让它调用stateCombo商店的加载功能。

  6. Ext.define('MyApp.models.Country',{
        extend: 'Ext.data.Model',
        requires: ['Ext.data.SequentialIdGenerator'],
        idgen: 'sequential',
        fields: [
            { name: 'name', type: 'string' }
        ]
    });
    
    Ext.define('MyApp.stores.Country', {
        model: 'MyApp.models.Country',
        data: [
            { name: 'China'},
            { name: 'Japan'},
            { name: 'Malaysia'}
        ]
    });
    
    Ext.define('MyApp.models.State',{
        extend: 'Ext.data.Model',
        requires: ['Ext.data.SequentialIdGenerator'],
        idgen: 'sequential',
        fields: [
            { name: 'state', type: 'string' }
        ],
        proxy: {
            type: 'ajax',
            method: 'post',
            url: '/CellEditing/FormServlet',
            reader: {
                type: 'json',
                root: 'data',
                successProperty: false
            }
        }
    });
    
    Ext.define('MyApp.stores.State', {
        model: MyApp.models.State
    });
    
    Ext.define('MyApp.views.CountryCombo', {
        extend: 'Ext.form.field.ComboBox',
        alias: 'widget.countrycombo',
        allowBlank: false,
        queryMode: 'local',
        valueField: 'name',
        displayField: 'name',
        store: MyApp.stores.Country.create()
    });
    
    Ext.define('MyApp.views.StateCombo', {
        extend: 'Ext.form.field.ComboBox',
        alias: 'widget.statecombo',
        queryMode: 'local',
        valueField: 'state',
        displayField: 'state',
        store: MyApp.stores.State.create()
    });
    
    Ext.form.Panel.create({
        title: 'Tester',
        renderTo: Ext.getBody(),
        items: [
            countryCombo = MyApp.views.CountryCombo.create(),
            stateCombo = MyApp.views.StateCombo.create()
        ]
    });
    
    countryCombo.on('beforeselect', function (combo, record, index, eOpts) {
        stateCombo.store.load({
            params: {data: record.get('name')}
        });
    });​
    

答案 1 :(得分:2)

使用loadData方法将数据加载到组合框。

yourCombo.store.loadData(obj.responsetext);

答案 2 :(得分:2)

您不能使用StateCombo,因为它是类的名称而不是对象实例本身。因此,代码StateCombo.storeStates.

无法访问商店

实际上,如果要访问商店以加载数据,可以通过两种方式实现。首先,因为在创建商店对象上将它保存在storeStates变量中,您可以访问它并使用它。 storeStates是全局变量或通过闭包知道。因此,通过编写以下子句,您可以执行所需的操作:

storeStates.loadData();

另一种方法是访问组合框控件然后获取其绑定存储。通过访问控制意味着不使用类名,但它是实例。要访问组合框控件,首先必须修改组合框的声明并通过设置itemId来定义实例名称:

Ext.define('StateCombo', {

itemId: 'stateCombo',
extend: 'Ext.form.field.ComboBox',
alias: 'widget.statecombo',
queryMode: 'local',
valueField: 'State',
displayField: 'State',
store: storeStates
});

一旦知道小部件,就可以通过以下方式找到它:

var arr = Ext.ComponentQuery.query('stateCombo');

现在,我们可以加载数据:

if (arr.length>0)
   arr[0].loadData();

答案 3 :(得分:1)

从编辑后的帖子中快速思考, 响应包含

{"data":[{"state":"sanghai"},{"state":"state2"}]}状态为小写,而在商店中则定义为fields: ['State']

另一件事是ajax响应是json字符串,所以应该在调用商店的loadData方法之前对其进行解码。

喜欢var response = Ext.decode(obj.responseText);

然后将loadData调用为StateCombo.storeStates.loadData(response.data);

答案 4 :(得分:1)

让我们看一下使用两个绑定到两个不同商店的组合框控件的示例。更改第一个组合框会引发事件,该事件会根据所选值重新加载(在我的示例中它会过滤)数据。然后重新加载第二个组合框的存储并重新填充控件。

此示例显示了模型,存储和视图如何协作和一起使用。通常它使用本地数据收集,但您可以轻松配置存储和代理,以便从服务器端获取数据:

 // Set up a model to use in our Store
 Ext.define('Countries', {
     extend: 'Ext.data.Model',
     fields: [
         {name: 'abbr', type: 'string'},
         {name: 'name',  type: 'string'}
     ]
 });

// The data store containing the list of states
var countries = Ext.create('Ext.data.Store', {
    fields: ['abbr', 'name'],
    model: 'Countries', 
    data : [
        {"abbr":"US", "name":"United States"},
        {"abbr":"FR", "name":"France"}
        //...
    ]
});

 // Set up a model to use in our Store
 Ext.define('States', {
     extend: 'Ext.data.Model',
     fields: [
         {name: 'cntry', type: 'string'},
         {name: 'abbr', type: 'string'},
         {name: 'name',  type: 'string'}
     ]
 });

// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
    autoLoad: false,
    fields: ['abbr', 'name'],
    model: 'States', 
    data : [
        {"cntry": "US", "abbr":"AL", "name":"Alabama"},
        {"cntry": "US", "abbr":"AK", "name":"Alaska"},
        {"cntry": "US", "abbr":"AZ", "name":"Arizona"},
        {"cntry": "FR", "abbr":"PR", "name":"Paris"}
        //...
    ],
    listeners: {
        beforeload: function () {

        }
    }

});


// Create the combo box, attached to the states data store
var a = Ext.create('Ext.form.ComboBox', {
    fieldLabel: 'Choose Country',
    store: countries ,
    queryMode: 'local',
    displayField: 'name',
    valueField: 'abbr',
    // Basically this code was tested on Simple Online ExtJS Code Editor
    // http://ext4all.com/post/simple-online-extjs-code-editor
    // so it was bounded to the codeoutput control 
    renderTo: 'codeoutput', 
    listeners: {
        // when we change the value of Countries combobox, this event is raised
        change: function(obj, newVal, oldVal, eOpts) {
            // we can also use states.filter() function in the same way
            states.filterBy ( function(record, id) {
            // newVal variable is available due to closure, so we can compare the row with the selected country and result appropriate notification
            if (record.get("cntry")==newVal) return true;
          });
        }
    }
});


// Create the combo box, attached to the states data store
var a = Ext.create('Ext.form.ComboBox', {
    fieldLabel: 'Choose State',
    store: states,
    queryMode: 'local',
    displayField: 'name',
    valueField: 'abbr',
    renderTo: 'codeoutput'
});