引子
当我们点击按钮时,按钮的值被改变“Click:20:34:42”,你如果仔细观察此次PostBack并不像点击一个普通Asp.net按钮一样,
页面并没有刷新,而且在回发过程中页面右上角还显示一个红色的提示框“正在加载....”:
通过HttpWatch我们可以看到返回值为:
box.$0.enable();
box.util.setDisabledControlBeforePostBack('');
box.$0.setText('Click:20:34:42');
box.util.updateViewState('EHgRUZXh0BQ5DbGljazoyMDozNDo0Mh4DJElEBQIkMGRkCbyzBkQ+Ki5LTj9GvIiyaApDFXM=',39);
返回的其实是一串字符串,其中包括修改按钮值的JavaScript脚本:box.$0.setText('Click:20:34:42');
ExtAspNet v2.0beta5中AJAX的实现
其实想实现AJAX也很简单,我们只需要知道在本次PostBack中有哪些控件的属性发生了变化,然后对于这些变化的属性生成一段JavaScript脚本就可以了。
在ExtAspNet v2.0beta5也是基于这个简单的考虑。
1. 首先在页面第一次加载时我们把按钮的Text属性保存下来(保存到ViewState)。
这里之所以将属性值字符串化后再取Hash值,是为了节约ViewState的大小(你想如果把多行文本框的Text保存在ViewState将会导致ViewState变的很大)。
2. 其次在AJAX回发时,我们取这个属性值和ViewState中的值比较,如果变化了则输出JavaScript脚本。
怎么样,是不是很简单。
ExtAspNet v2.0.6中AJAX的实现
为什么会想着改进,这源于我写 上一篇文章时看着满屏幕的HashCode,很是心烦。我们能否摆脱这个烦人的ViewState?
还是那个老问题:怎么知道本次回发时某个属性改变了。
其实在页面回发时,所有控件的ViewState都被重新装载了,因此我们只需要比较控件装载完ViewState的值和即将渲染到页面时ViewState的值不就可以了。
我们已经明确知道在控件中有个事件叫 OnPreRender,它表示的就是在将控件渲染到页面之前的那个阶段,我们已经多次用到了。
我们只需要找到 控件刚刚装载完毕ViewState的那个时刻不就可以了。
还是来看下 自定义控件的生命周期:
这个时刻应该是在OnLoad之前和LoadViewState之后(也可能是LoadPostData之后),很可惜的是居然没有一个OnPreLoad事件!!
可能有网友说,你在OnLoad时检查ViewState不就行了么?
-----其实不然,控件的OnLoad执行时,Page的Page_Load已经执行结束,开发人员可能在Page_Load中已经改变了控件的属性值。
其实办法还是有的,我们为控件注册Page的OnPreLoad事件不就行么,如下代码所示:
最后我们只需要比较控件在 OnPreLoad 时刻的属性值和OnPreRender时刻的属性值,就知道这个属性在本次PostBack是否被用户所改变了。
后记
一件问题常常有多种解决办法,先实现功能再考虑优化往往是一个正确的选择。
Happy coding.
在最新发布的
ExtAsp.Net v2.0.6 版本中,有一个重大更新:
------优化AJAX的内部实现,每个页面保存的ViewState现在减少1/3左右(重要更新)。
如果你对v2.0beta5和v2.0.6中一些页面ViewState大小的对比结果感兴趣的话,可以看 上一篇博客。
ExtAspNet中的AJAX
在ExtAspNet的产品描述中,有这样一句话“原生的AJAX支持”,其实这也是我们非常推崇的一个特性。
所谓的“原生”就是开发人员不需要做任何设置,ExtAspNet中的PostBack默认就是一个AJAX过程。
考虑一个简单的例子:
------优化AJAX的内部实现,每个页面保存的ViewState现在减少1/3左右(重要更新)。
如果你对v2.0beta5和v2.0.6中一些页面ViewState大小的对比结果感兴趣的话,可以看 上一篇博客。
ExtAspNet中的AJAX
在ExtAspNet的产品描述中,有这样一句话“原生的AJAX支持”,其实这也是我们非常推崇的一个特性。
所谓的“原生”就是开发人员不需要做任何设置,ExtAspNet中的PostBack默认就是一个AJAX过程。
考虑一个简单的例子:
<
ext:PageManager
ID
="PageManager1"
runat
="server"
/>
< ext:Button ID ="Button1" runat ="server" OnClick ="Button1_Click" Text ="Button" >
</ ext:Button >
< ext:Button ID ="Button1" runat ="server" OnClick ="Button1_Click" Text ="Button" >
</ ext:Button >
protected
void
Button1_Click(
object
sender, EventArgs e)
{
Button1.Text = " Click: " + DateTime.Now.ToLongTimeString();
}
{
Button1.Text = " Click: " + DateTime.Now.ToLongTimeString();
}
当我们点击按钮时,按钮的值被改变“Click:20:34:42”,你如果仔细观察此次PostBack并不像点击一个普通Asp.net按钮一样,
页面并没有刷新,而且在回发过程中页面右上角还显示一个红色的提示框“正在加载....”:
![](https://i-blog.csdnimg.cn/blog_migrate/59ff2bfca82ff1c4b181b21af9985db9.gif)
通过HttpWatch我们可以看到返回值为:
box.$0.enable();
box.util.setDisabledControlBeforePostBack('');
box.$0.setText('Click:20:34:42');
box.util.updateViewState('EHgRUZXh0BQ5DbGljazoyMDozNDo0Mh4DJElEBQIkMGRkCbyzBkQ+Ki5LTj9GvIiyaApDFXM=',39);
返回的其实是一串字符串,其中包括修改按钮值的JavaScript脚本:box.$0.setText('Click:20:34:42');
ExtAspNet v2.0beta5中AJAX的实现
其实想实现AJAX也很简单,我们只需要知道在本次PostBack中有哪些控件的属性发生了变化,然后对于这些变化的属性生成一段JavaScript脚本就可以了。
在ExtAspNet v2.0beta5也是基于这个简单的考虑。
1. 首先在页面第一次加载时我们把按钮的Text属性保存下来(保存到ViewState)。
//
如果不是ExtAspNetAjax回发,则保存属性到ViewState
if ( ! IsExtAspNetAjaxPostBack)
{
ViewState[ " Text_HashCode " ] = Text.GetHashCode().ToString( " X8 " );
}
因此也就有你在
这一篇文章中看到的这个截图了:
if ( ! IsExtAspNetAjaxPostBack)
{
ViewState[ " Text_HashCode " ] = Text.GetHashCode().ToString( " X8 " );
}
![](https://i-blog.csdnimg.cn/blog_migrate/e92f48d17a0f577312ccab20d407ad70.gif)
这里之所以将属性值字符串化后再取Hash值,是为了节约ViewState的大小(你想如果把多行文本框的Text保存在ViewState将会导致ViewState变的很大)。
2. 其次在AJAX回发时,我们取这个属性值和ViewState中的值比较,如果变化了则输出JavaScript脚本。
string
currentText
=
Text.GetHashCode().ToString(
"
X8
"
);
if (currentText != ViewState[ " Text_HashCode " ].ToString())
{
// 输出 box.$0.setText('Click:20:34:42');
ViewState[ " Text_HashCode " ] = currentText;
}
if (currentText != ViewState[ " Text_HashCode " ].ToString())
{
// 输出 box.$0.setText('Click:20:34:42');
ViewState[ " Text_HashCode " ] = currentText;
}
怎么样,是不是很简单。
ExtAspNet v2.0.6中AJAX的实现
为什么会想着改进,这源于我写 上一篇文章时看着满屏幕的HashCode,很是心烦。我们能否摆脱这个烦人的ViewState?
还是那个老问题:怎么知道本次回发时某个属性改变了。
其实在页面回发时,所有控件的ViewState都被重新装载了,因此我们只需要比较控件装载完ViewState的值和即将渲染到页面时ViewState的值不就可以了。
我们已经明确知道在控件中有个事件叫 OnPreRender,它表示的就是在将控件渲染到页面之前的那个阶段,我们已经多次用到了。
我们只需要找到 控件刚刚装载完毕ViewState的那个时刻不就可以了。
还是来看下 自定义控件的生命周期:
![](https://i-blog.csdnimg.cn/blog_migrate/e26e6d70cf883e69a435bad38d1d03ad.gif)
这个时刻应该是在OnLoad之前和LoadViewState之后(也可能是LoadPostData之后),很可惜的是居然没有一个OnPreLoad事件!!
可能有网友说,你在OnLoad时检查ViewState不就行了么?
-----其实不然,控件的OnLoad执行时,Page的Page_Load已经执行结束,开发人员可能在Page_Load中已经改变了控件的属性值。
其实办法还是有的,我们为控件注册Page的OnPreLoad事件不就行么,如下代码所示:
protected
override
void
OnInit(EventArgs e)
{
base .OnInit(e);
if (Page != null )
{
// 只有在ExtAspNet的AJAX回发时才注册Page.PreLoad事件
if (IsExtAspNetAjaxPostBack)
{
Page.PreLoad += new EventHandler(OnPreLoad);
}
}
}
{
base .OnInit(e);
if (Page != null )
{
// 只有在ExtAspNet的AJAX回发时才注册Page.PreLoad事件
if (IsExtAspNetAjaxPostBack)
{
Page.PreLoad += new EventHandler(OnPreLoad);
}
}
}
最后我们只需要比较控件在 OnPreLoad 时刻的属性值和OnPreRender时刻的属性值,就知道这个属性在本次PostBack是否被用户所改变了。
后记
一件问题常常有多种解决办法,先实现功能再考虑优化往往是一个正确的选择。
Happy coding.