用 PHPRPC 实现 Ajax 级联下拉菜单 打印 E-mail
级联下拉菜单就是从一个下拉菜单中选中一项后,相应的另一个下拉菜单的内容会随之改变。

一般来说,最简单的,就是每次选中都提交一次表单,刷新整个页面。这也是用户体验度最差的。

另一种是把所有选项在第一次加载时就全部载入整个页面中的 javascript 数组中,然后级联通过 JavaScript 来控制,在整个数据量不大时,这是一个不错的实现无刷新并且快速的方法,但是当整个数据量非常大时,这种方法就会使第一次加载变得非常慢了。

还有就是采用 Ajax 方式,即开始只载入第一层菜单的内容,当用户选中第一层菜单的某项时,再通过 XmlHttpRequest 来获取相应选项所对应的第二层菜单的内容。这种方式效果最好,但是采用传统方式来编写这样的 Ajax 程序代码量会比较多。而且如果设计不好,服务器端返回菜单内容的程序的可复用性也会很差。

但是在本文中你会看到用 PHPRPC 来实现这种 Ajax 效果是多么的简单,并且还会具有非常高的可复用性。


本文以省市两级级联下拉菜单为例,为了举例方便,本文中采用的是 SQLite 数据库,因为这个文件型数据库比较容易部署,而且查询效率很高(当然创建该数据库的效率不高,但创建仅一次而已,该数据库在该程序中内容是不变的),不过服务器需要安装 SQLite 扩展。

这个数据库中的表只有 2 个,一个 province 表,一个 city 表。province 表中,只有 id 和 name 两个字段,分别是省份编号(主键)和省名。city 表中,有 id、name 和 pid 三个字段,id 是城市编号,name 是城市名,pid 是城市所在省的编号,与 province 表中的省份编号相对应。

创建该数据库的程序这里就不给出来了,它包含在后面提供的实例下载中。

下面来看看创建这个程序的服务器端有多么简单,为了提高可复用性,我们把服务器端分为了 2 个文件,一个是 function.php,另一个是 rpc.php。function.php 中定义了实际的远程调用函数,但是他们也可以作为服务器端的本地函数调用,你会发现他们跟服务器端的普通函数没有任何区别:

下载: function.php
<?php
$sqlite 
= new SQLiteDatabase('area.db'
);
 
function 
get_province
() {
    global 
$sqlite
;
    
$sql "select * from province order by id"
;
    return 
$sqlite->arrayQuery($sqlSQLITE_ASSOC
);
}
 
function 
get_city($pid
) {
    global 
$sqlite
;
    
$pid sqlite_escape_string($pid
);
    
$sql "select * from city where pid = $pid order by id"
;
    return 
$sqlite->arrayQuery($sqlSQLITE_ASSOC
);
}
?> 

而 rpc.php 更加简单,它是提供给客户端调用的接口,它只有 3 行语句:

下载: function.php
<?php
require_once('function.php'
);
require_once(
'phprpc_server.php'
);
new 
phprpc_server(array('get_province''get_city'
));
?> 

其中最后一句,就是指定哪些函数要暴露给客户端。只有指定的函数客户端才可以调用,这样可以保证服务器的安全性。

服务器端到此就创建完了。你会发现服务器端只负责把数据查询出来返回给客户端就完事了,其它的不做任何处理。

那么下面该看一看客户端了,客户端虽然很简单,但是我还是把它分成了两个文件,一个 js 文件,一个 html 文件,你会发现用 PHPRPC,客户端都不需要用 PHP。

下载: area.js
// 创建 phprpc 客户端对象 rpc
phprpc_client.create('rpc'
);
 
var 
city = []; 
// 用于缓存已加载的城市数据
 
/* 
 * 清除 select 中的选项,该方法可复用
 *
 * so: 要清除选项的 select 对象
 *
 */
function clear_select(so
) {
    for (var 
so.options.length 1> -1i
--) {
        
// 有些浏览器不支持 options 属性的 remove 方法,
        // 但支持 DOM 的 removeChild 方法(比如:Konqueror)
        
if (so.options.remove
) {
            
so.options.remove(i
);
        }
        else {
            
so.removeChild(so.options[i
]);
        }
    }
}
 
/*
 * 设置 select 中的选项,该方法可复用
 *
 * so: 要设置选项的 select 对象
 *  d: 选项数据数组
 * vf: 选项值所对应的数组中的字段名
 * tf: 选项文本所对应的数组中的字段名
 */
function set_select(sodvftf
) {
    for (var 
0d.lengthni
++) {
        var 
opt document.createElement('option'
);
        
opt.text d[i][tf
];
        
opt.value d[i][vf
];
        
// 有些浏览器不支持 options 属性的 add 方法,
        // 但支持 DOM 的 appendChild 方法(比如:Konqueror)
        
if (so.options.add
) {
            
so.options.add(opt
);
        }
        else {
            
so.appendChild(opt
);
        }
    }
}
 
// 设置省份的下拉菜单
function set_province_select(d
) {
    var 
so document.getElementById('province'
);
    
set_select(sod'id''name'
);
    
// 设置首选省份的城市下拉列表
    
change_province(1
);
}
 
// 设置城市的下拉菜单
function set_city_select(dvftf
) {
    var 
so document.getElementById('city'
);
    
// 清空原有选项
    
clear_select(so
);
    
// 设置新选项
    
set_select(sodvftf
);
}
 
// 当省份改变,相应的改变城市列表
function change_province(pid
) {
    
// 如果已缓存,则直接显示缓存中的列表
    
if (city[pid
]) {
        
set_city_select(city[pid], 'id''name'
);
    }
    else {
        
// 否则,先显示载入中
        
set_city_select([['''Loading...']], 01
);
        
// 然后调用远程过程载入城市信息
        // 调用远程过程时,最后一个参数指定的是回调函数
        
rpc.get_city(pid, function (result
) {
            
// 把载入的数据放入缓存
            
city[pid] = result
;
            
// 更新城市列表
            
set_city_select(result'id''name'
);
        });
    }
}
 
// 定义当 rpc 客户端初始化(use_service)完毕后执行的内容
rpc.onready 
= function () {
    
// 调用获取省份内容的远程过程,并设置回调函数为 set_province_select
    
rpc.get_province(set_province_select
);

下载: index.html
<html>
<
head
>
<
script type="text/javascript" src="phprpc_client.js"></script
>
<
script type="text/javascript" src="area.js"></script
>
</
head
>
<
body onload="rpc.use_service('rpc.php');"
>
<
select id="province" onchange="change_province(this.value);"></select
>
<
select id="city"></select
>
</
body
>
</
html

上面的 html 中包含的 phprpc_client.js 是压缩版本(因为不需要用到加密,这里是 lite 压缩版)的,这样可以免去包含多个 js 文件的麻烦。

大家会发现这个程序不但可复用性好(比如 clear_select 和 set_select 两个函数也可以在其它程序中使用),而且使得整个程序的思路清晰,比如那个缓存功能,在这里实现的就非常的简单,而且效果也非常的好。
发表评论
网友评论
作者 访客 于 2008-06-27 11:38:44
:eek :roll :p 8) ;) :grin :) :x :( :cry :? :sigh :zzz :upset
lk
作者 访客 于 2008-07-04 11:47:56
精油 
论文发表 
上海翻译公司 
上海翻译 
英语培训 
英语口语 
神经性皮炎 
皮炎 
湿疹 
荨麻疹 
慢性荨麻疹 
藏獒 
液压缸 
油缸 
破碎机 
北京旅游 
北京旅行社 
条码机 
条码打印机 
条形码打印机 
阴茎增大 
伟哥 
发酵罐 
肠炎 
结肠炎 
直肠炎 
慢性肠炎 
慢性结肠炎 
结肠炎的治疗 
溃疡性结肠炎 
慢性结肠炎的治疗 
大豆床上用品 
保健内衣 
羊绒内衣 
大豆纤维面料 
团购礼品 
移民 
热电偶插头 
测温线 
热电阻 
煤气发生炉 
两段式煤气发生炉 
环保节能型煤气发生炉 
硅碳棒 
吸塑机 
纸管机 
无缝管 
合金管 
无缝管 
无缝钢管 
高血压 
产品设计 
无纸记录仪 
红外测温仪 
无纸记录仪 
韩国服装 
韩版服装 
韩国服饰 
丝锥 
挤压丝锥 
非标丝锥 
梯形丝锥 
螺纹环规 
men spa beijing 
men massage beijing 
pearl jewelry 
Beijing Tour 
china Tour 
beijing Tour 
china Tour 
beijing Tour 
China Necklace Wholesale 
China Bracelet Wholesale 
China Ring wholesale 
China gemstone beads wholesale 
China Jewelry Accessories wholesale 
China Semiprecious beads wholesale 
replica handbag 
replica tiffany 
replica watches 
louis vuitton replica 
chanel replica 
gucci replica 
Chinese language 
Chinese learn 
learning Chinese 
learn mandarin 
ecosway 
gasifier 
coal gas 
coal gasification 
pro dj cases 
beijing tour 
beijing tours 
beijing travel 
beijing tours 
china tour 
beijing 
china tours 
china travel 
beijing china 
china beijing 
beijing hotel 
beijing hotels 
China Flights 
carved fireplace 
stone bathtub 
marble fountain 
marble bench 
marble fireplace 
marble sculpture 
marble columns 
marble lions 
marble doorway 
marble gazebo 
marble pillar 
marble fireplace surround 
marble statue 
marble bathtub
cv
作者 访客 于 2008-07-15 16:07:39
移民 
投资移民 
加拿大移民 
技术移民 
移民加拿大 
澳洲技术移民 
德国移民 
移民澳洲 
澳洲移民 
出国移民 
移民出国 
英国移民 
澳大利亚移民 
加拿大投资移民 
加拿大技术移民 
美国留学 
法国留学 
北欧留学 
瑞典留学 
芬兰留学 
澳洲留学 
除湿机 
抽湿机 
工业除湿机 
空气净化器 
空气净化机 
步进电机 
联轴器 
真空泵 
工作服 
职业装 
北京工作服 
定做工作服 
北京二手空调回收 
空调维修 
物资回收 
防腐设备 
风机 
铠装热电偶 
精密铸造 
美术培训 
美术高考 
美术高考培训 
画室 
北京画室 
谐波治理 
无功补偿 
防腐管道 
英美制丝锥 
继电保护测试仪 
日语学校 
日语培训 
安装卫星电视 
安装卫星天线 
北京安装卫星电视 
北京安装卫星天线 
针孔摄像机 
望远镜 
夜视仪 
探测狗 
窃听器 
无线耳机 
屏蔽器 
金属探测器 
隔墙监听器 
国标舞 
拉丁舞 
喷码机 
针孔摄像机 
烤瓷牙 
除沫器 
土壤水分速测仪 
土壤水分测定仪 
土壤水分测量仪 
土壤墒情记录仪 
农药残留速测仪 
土壤化肥速测仪 
土壤养分测试仪 
信号隔离器 
信号分配器 
隔离器 
温度变送器 
电流变送器 
配电器 
隔离配电器 
隔离模块 
糖尿病足 
煤气发生炉 
高低温试验箱 
振动试验台 
恒温恒湿试验箱 
恒温恒湿箱 
恒温箱 
振动台 
盐雾箱 
老化台 
盐雾试验箱 
高低温箱 
低温试验箱 
振动试验机 
合同纠纷 
房产纠纷 
劳动纠纷 
房地产律师 
制氮机 
在职研究生 
液体壁纸 
清水模板 
冷弯型钢 
roll forming 
开口闪点仪 
凝固点仪 
闭口闪点仪 
运动粘度仪 
粘度仪 
抗乳化测定仪 
丝网除沫器 
气液过滤网 
除雾器 
丝网除雾器 
波纹填料 
三菱电机空调 
牛仔服 
牛仔服装厂 
牛仔休闲 
牛仔裤 
牛仔品牌 
牛仔专卖店 
虹吸 
虹吸雨水 
虹吸排水 
有压流 
同层排水 
walk throught metal detector 
恒温器 
马达保护器 
热保护器 
温度开关 
温控器 
过流保护器

发表评论
用户访客
标题
BBCode:Web AddressEmail AddressBold TextItalic TextUnderlined TextQuoteCodeOpen ListList ItemClose List
评论



< 上一篇   下一篇 >