着名品牌服务器控件(Control)携手奥运冠军客户端HTML标签作为形象代言人新形象以极速体验为主题既诠释了服务器控件本身强大的信息处理能力也表现客户端HTML标签希望用灵动和亲切来证明自己的决心与态度
■ 内与外 property与attribute
近日Google发布除英文外的唯一名称谷歌中国用户一片哗然 暂且不论这个谷歌是不是比胡弋更合适但Google想借此阐述产品内涵取悦中国用户之心路人皆知今年Web引无数风投竞折腰亿美金撒向大陆都是钱于是网站们如同川剧变脸摇身一变换成一张张博客书签圈圈的面庞冷静思考在信息过剩特别是同质化严重的前提下数据挖掘用户体验成为网站关键有人戏称三分长相(内容)七分打扮(内容聚集和用户体验)即是如此人机交互设计从可有可无提升到必不可少Ajax技术变火也就不奇怪了
服务器端处理总是WEB应用系统的核心功能大多数的信息处理在服务器端完成但如果把所有功能都放在服务器端让页面带着几百几千字节的ViewState在网络中来回穿梭那可不是恶心那是相当的恶心所以我们需要客户端充当服务器端的代言人通过执行脚本程序来分担一些系统功能让用户更爽让服务器更轻松
通过控件与用户完成交互但就客户端浏览器而言它从未听过也不和控件打交道它所熟悉的是HTML标签和客户端脚本程序要让客户端充当服务器端的代言人就必须让二者交流与沟通即动态添加客户端行为动态生成客户端脚本控件行为与客户端行为映射等
attribute和property是一对有趣的近义词MSDN中有这么一句话在 ASPNET 服务器控件的标记中可以使用属性 (attribute) 来设置属性 (property) 值属性设置属性?头晕目眩中简单地理解property是类的成员attribute是类的外观前者是品牌自身特征后者为代言人特征前者可以通过后者来展示自己反映到控件与对应HTML标签控件状态是property标签中对应的字符串是attribute即浏览器所看到的服务器端控件的外形
■ 宣布 添加客户端行为
HTTP响应流就是一串字符流页面生成一个HtmlTextWriter实例专门收集控件们生成的HTML标记文本它按控件树的次序让控件的RenderControl方法检查自己的Visible属性如果为真就调用控件的Render方法向实例添加标记文本搞定后调用RenderChildren方法向下递归传递所以在页面调用控件Render方法之时或之前可以在动态地修改标签中的Attribute以组装成相应的标记文本
向控件添加客户端行为最简单的方法是在apsx文件中的标签直接声明对应的Attribute或以编程方式调用控件Attributes 集合的Add方法即向客户端浏览器宣布我的代言人是老徐~~
<%@ Page Language=C# %>
<script runat=server>
protected void Page_Load(object sender EventArgs e){
// 为btnTest控件添加onmouseover和onmouseout客户端行为
btnTestAttributesAdd(onmouseoverMakeRed(););
btnTestAttributesAdd(onmouseoutRestoreColor(););
}
</script>
<html><head runat=server>
<script language=JavaScript>
var previousColor;
// 改变前景色
function MakeRed(){
previousColor = windoweventlor;
windoweventlor = #FF;
}
// 恢复原前景色
function RestoreColor(){
windoweventlor = previousColor;
}
</script>
</head>
<body>
<form id=form runat=server>
<asp:button id=btnTest text=btnTest runat=server />
</form>
</body></html>
■ 注入 动态添加客户端脚本
除了直接在ASPx文件中显式声明外Page类还提供了一些方法用于动态创建客户端脚本所谓的动态生成脚本实际上就是生成对应的脚本字符串然后使用Page类提供的ReGISterClientScriptBlock RegisterOnSubmitStatement等方法注入到HtmlTextWriter实例中合适的位置同时ASPNET还提供若干方法用于辅助生成脚本无非就是加点隐藏输入域数组之类的东西
控件也可以在OnPreRender方法调用这些方法通知页面添加所需脚本字符串之所以不在Render方法中实现是因为HtmlTextWriter实例在被传递到控件手上时Page类已经完成在HtmlTextWrite实例中生成对应文本慢了一步下例为页面回发添加一个确定对话框
<%@ Page Language=C# %>
<script runat=server>
protected void Page_Load(Object sender EventArgs e){
String scriptText = return confirm(要提交吗?);
//添加页面提交时执行的脚本 RegisterOnSubmitStatement(ConfirmSubmit scriptText);
}
</script>
<html><head></head><body>
<form id=form runat=server>
<asp:button id=btnTest text=PostBack runat=server />
</form></body></html>
■ 携手 GetPostBackEventReference方法
很多时候我们希望客户端行为能够和相应的服务端行为携起手来共同完成一个完整的系统功能即客户端行为能够触发相应的服务器端行为即两者映射在中本质上是把页面为原子回发单位客户端行为只能在页面回发之前向隐藏标志域里写入带有自身特征的数据页面回发后控件们通过检查隐藏标志域的数据来触发相应的行为
客户端与服务端携手典型例子有两个一是GetPostBackEventReference方法它可以引发带有特征数据的页面回传一是大名鼎鼎的验证器构架除此之外标准控件也有若干是通过客户端行为来实现下面我们以前者为例演示完整的生成客户端处理回发服务端处理过程
public class MyControl : Control IPostBackEventHandler{
//定义Number属性
public int Number{
get{
if ( ViewState[Number] !=null )
return (int) ViewState[Number];
else
return ;
}
set { ViewState[Number] = value; }
}
//依赖于用户操作的事件处理请参考《随想十一》
// eventArgument为事件数据这里由GetPostBackEventReference设置
public void RaisePostBackEvent(string eventArgument){
if ( eventArgument == inc ) Number ++;
if ( eventArgument == dec ) Number ;
}
//生成控件对应的HTML标记文本
//除生成Number属性文本外还生成两个引发回发并带着回发事件参数的超链接
// GetPostBackEventReference 方法发出启动回发的客户端脚本并提供引用
protected override void Render(HtmlTextWriter writer){
writerWrite(控件值: + NumberToString() + );
writerWrite(<a href=\JavaScript: + PageGetPostBackEventReference(thisinc) + \>+</a>);
writerWrite( or );
writerWrite(<a href=\Javascript: + PageGetPostBackEventReference(thisdec) + \></a>);
}
}
由于ASPNET是以页面为原子回发单位代言人与品牌之间的沟通和联系要付出巨大的性能代价要改善只能打破以页面作为原子回发单位的制度