2

我得到一个 json 数组字符串作为来自页面的响应。我想用组合框绑定它。

这是给我json数组字符串的成功块:

json 数组字符串如下所示:

显示 json 数组字符串的消息框

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

问候,

编辑:

这是我尝试的最新代码:

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

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

4

5 回答 5

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

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')}
    });
});​
于 2012-10-22T22:28:52.820 回答
2

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

yourCombo.store.loadData(obj.responsetext);
于 2012-10-13T05:31:49.917 回答
2

您不能使用 StateCombo,因为它是类的名称,而不是对象实例本身。因此无法通过代码访问商店StateCombo.storeStates.

实际上,如果你想访问 store 来加载数据,你可以通过两种方式来实现。首先,因为在创建存储对象时将其保存在 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();
于 2012-10-23T14:14:23.330 回答
1

只是从编辑的帖子中快速思考,回复包含

{"data":[{"state":"sanghai"},{"state":"state2"}]}在存储时以小写形式表示它被定义为fields: ['State']

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

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

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

于 2012-10-21T12:18:27.950 回答
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'
});
于 2012-10-21T21:44:42.280 回答