前言
ExtJS在修改这样的页面上赋值是很方便的,在正文中1.2.1代码中可以看出,一行代码就可以搞定,但这是对于普通控件而言,如文本框。对于ComboBox可没这么简单...
版本
Ext JS Library 3.0.0
正文
一、问题
1.1 截图
![[ExtJS]设置级联菜单的默认值](http://img.e-com-net.com/image/product/14904e9db01940a99f89fd50b3ae20dc.png)
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)之类的代码可以在我以前的文章里面找得到说明。遇到问题除了抱怨还可以选择消灭,那种解决后的快感是非常深刻的,这个问题很早就解决了,一直没时间写,现在仍然记得清晰 :)