前言
ExtJS在修改这样的页面上赋值是很方便的,在正文中1.2.1代码中可以看出,一行代码就可以搞定,但这是对于普通控件而言,如文本框。对于ComboBox可没这么简单...
版本
Ext JS Library 3.0.0
正文
一、问题
1.1 截图
1.2 代码
1.2.1 前端代码
//
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 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 第一步,手动触发一级菜单选择事件
// 加载数据
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 修改级联
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
本文转自over140 51CTO博客,原文链接:http://blog.51cto.com/over140/586530,如需转载请自行联系原作者