您的位置:首页 > Web前端 > JavaScript

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

2010-06-12 20:48 726 查看
前言

   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(1, new Combox()

{

Id = 1,

Name = "长沙市"

});

Citys.Add(2, new Combox()

{

Id = 1,

Name = "岳阳市"

});

Citys.Add(3, new Combox()

{

Id = 2,

Name = "深圳市"

});

Citys.Add(4, new 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<string, int> result = new Dictionary<string, int>();

result.Add("combo1", 2);

result.Add("combo2", 2);

return JavaScriptConvert.SerializeObject(result);

}

class Combox

{

public int Id { get; set; }

public string Name { get; set; }

}

    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)之类的代码可以在我以前的文章里面找得到说明。遇到问题除了抱怨还可以选择消灭,那种解决后的快感是非常深刻的,这个问题很早就解决了,一直没时间写,现在仍然记得清晰 :)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息