[ExtJS]设置级联菜单的默认值


前言

   ExtJS在修改这样的页面上赋值是很方便的,在正文中1.2.1代码中可以看出,一行代码就可以搞定,但这是对于普通控件而言,如文本框。对于ComboBox可没这么简单...

 

版本

  Ext JS Library 3.0.0

 

正文

  一、问题

    1.1  截图

      

    1.2  代码

      1.2.1  前端代码

    <script type="text/javascript">
        
//
        function ExtStore(url)
        {
            
return new Ext.data.Store({
                proxy: 
new Ext.data.HttpProxy({
                    url: url
                }),
                reader: 
new Ext.data.JsonReader({
                    totalProperty: 
'count',
                    root: 
'result'
                },
                [
                    { name: 
'Id' },
                    { name: 
'Name' }
                ])
            });
        }
        
        Ext.onReady(
function() {
            Ext.QuickTips.init();
            Ext.form.Field.prototype.msgTarget 
= 'side';
            
            
var store1 = ExtStore('combox.aspx?method=GetProvinces');
            
var store2 = ExtStore('combox.aspx?method=GetCitys');
            
            
var combo2 = ComboBox('combo2','二级菜单',store2);
            
var combo1 = new Ext.form.ComboBox({
                mode: 
'remote',
                fieldLabel:
'一级菜单',
                name:
'combo1',
                editable : 
false,
                typeAhead: 
true,
                triggerAction: 
'all',
                displayField:
'Name',
                valueField:
'Id',
                selectOnFocus:
true,
                store:store1,
                listeners: {
                    
'select'function(combo, record){
                        
var id = record.get('Id');
                        
if(id)
                        {
                            
//清空二级菜单选项
                            combo2.setRawValue('');
                            store2.proxy 
= new Ext.data.HttpProxy({
                                url:String.format(
'combox.aspx?method=GetCitys&Province={0}',id)
                            });
                            store2.load();
                        }
                    }
                }
            });
            
            
var form1 = new Ext.FormPanel({
                layout: 
'form',
                autoHeight: 
true,
                frame: 
true,
                renderTo: Ext.getBody(),
                title: 
'<center style="curor:hand" onclick="window.location.reload();">表单控件</center>',
                style: 
'margin-left:auto;margin-right:auto;width:500px;margin-top:8px;',
                
//设置标签对齐方式
                labelAlign: 'right',
                
//设置标签宽
                labelWidth: 170,
                
//设置按钮的对齐方式
                buttonAlign:'center',
                
//默认元素属性设置
                defaults:{  width:180   },
                items: [
                    combo1,
                    combo2
                ]
            });
            
            
//加载数据
            Ext.Ajax.request({
                url: 
'combox.aspx?method=Detail',
                method: 
'GET',
                callback: 
function (options, success, response) {
                    
if(success && response.status == 200){
                        
//将值批量赋值
                        form1.form.setValues(Ext.util.JSON.decode(response.responseText))
                    }
                }
            }); 
        });
    
</script>

      1.2.2  后台代码

    static IList<Combox> Provinces = new List<Combox>();
    
static IDictionary<int, Combox> Citys = new Dictionary<int, Combox>();

    
static combox()
    {
        Provinces.Add(
new Combox() { Id = 1, Name = "湖南省" });
        Provinces.Add(
new Combox() { Id = 2, Name = "广东省" });

        Citys.Add(
1new Combox()
        {
            Id 
= 1,
            Name 
= "长沙市"
        });

        Citys.Add(
2new Combox()
        {
            Id 
= 1,
            Name 
= "岳阳市"
        });

        Citys.Add(
3new Combox()
        {
            Id 
= 2,
            Name 
= "深圳市"
        });

        Citys.Add(
4new Combox()
        {
            Id 
= 2,
            Name 
= "珠海市"
        });
    }

    
protected void Page_Load(object sender, EventArgs e)
    {

    }

    
/// <summary>
    
/// 获取所有省份数据
    
/// </summary>
    
/// <returns></returns>
    public void GetProvinces()
    {
        Response.Write(
new StringBuilder().Append("{count:")
            .Append(Provinces.Count)
            .Append(
",result:")
            .Append(JavaScriptConvert.SerializeObject(Provinces))
            .Append(
'}')
            .ToString());
    }

    
/// <summary>
    
/// 获取省下面的市区数据
    
/// </summary>
    
/// <returns></returns>
    public void GetCitys()
    {
        IList
<Combox> result = new List<Combox>();
        
int Province = Convert.ToInt32(Request.QueryString["Province"]);
        
foreach (KeyValuePair<int, Combox> data in Citys)
        {
            
if (data.Value.Id == Province)
                result.Add(
new Combox() { Id = data.Key, Name = data.Value.Name });

        }
        Response.Write(
new StringBuilder().Append("{count:")
            .Append(result.Count)
            .Append(
",result:")
            .Append(JavaScriptConvert.SerializeObject(result))
            .Append(
'}')
            .ToString());
    }

    
public override string Detail()
    {
        IDictionary
<stringint> result = new Dictionary<stringint>();
        result.Add(
"combo1"2);
        result.Add(
"combo2", 2);
        
return JavaScriptConvert.SerializeObject(result);
    }

    
class Combox
    {
        
public int Id { getset; }
        
public string Name { getset; }
    }

    1.3  代码说明

      1.3.1  后台代码中使用的数据仅用测试用

      1.3.2  意图:加载的时候就默认选择广东省——珠海市

 

  二、问题分析

    ComboBox延迟加载导致。

 

  三、解决办法

    2.1  让ComboBox赋值后显示对应的Name,而不是Id

      在Ext.Ajax.request执行前加一句“store1.load();”即可。

       

    2.2  ComboBox级联赋值

      级联赋值可没这么简单了,需要手动触发事件,这里尝试了很长时间才出结果。

      2.2.1  第一步,手动触发一级菜单选择事件

            store1.load();
            
            
//加载数据
            Ext.Ajax.request({
                url: 
'combox.aspx?method=Detail',
                method: 
'GET',
                callback: 
function (options, success, response) {
                    
if(success && response.status == 200){
                        
//将值批量赋值
                        form1.form.setValues(Ext.util.JSON.decode(response.responseText))
                        
                        
var comboValue1 = combo1.getValue();
                        
var selectRecord;
                        store1.each(
function(record){
                            
if(record.data.Id == comboValue1)
                                selectRecord 
= record;
                        });
                        combo1.fireEvent(
'select',combo1,selectRecord);
                    }
                }
            }); 

        这里发现手动触发得自己传入record的参数,不然里面去不到值。

      2.2.2  修改级联

                            store2.load({
                                callback :
function(r,options,success){
                                    
if(success){
                                        
if(IsLoad)
                                        {
                                            combo2.setValue(comboValue2);
                                            IsLoad 
= false;
                                        }
                                    }
                                }
                            });

        代码说明:

          a).  IsLoad是全局变量,用来控制仅设置一次默认值

          b).  很容易又会犯触发菜单一就直接给菜单二赋值的错,注意这里因为菜单二还没有加载完,所有如果直接在触发事件后面写赋值,出来仍然是数字。

      2.2.3  最终效果图

        

 

  四、代码下载

    /Files/over140/2010/6/combox2010-6-12.rar

 

  五、维护

    5.1  2010-6-13

      此文对本文的问题有所启发:http://hi.baidu.com/pure_adoration/blog/item/7146f0264608730a908f9d5d.html

 

  六、转载保留

    博客园:http://www.cnblogs.com/

      农民伯伯:http://over140.cnblogs.com/

 

结束

  注意代码中的如PageBase、 ComboBox('combo2','二 级菜单',store2)之类的代码可以在我以前的文章里面找得到说明。遇到问题除了抱怨还可以选择消灭,那种解决后的快感是非常深刻的,这个问题很早就解决了,一直没时间写,现在仍然记得清晰 :)

posted @ 2010-06-12 20:48  农民伯伯  阅读(1838)  评论(0编辑  收藏  举报