随着jQuery的流行,开发者们越来越多地尝试将其与ASP.NET和AJAX.NET的框架结合使用。虽然jQuery提供了强大的AJAX机制,但在ASP.NET环境中使用它可能会显得笨拙和不自然。相比之下,使用ASP.NET的UpdatePanel来实现AJAX功能,并利用jQuery的selector功能,似乎是一个更自然的选择。然而,这种集成方式并不简单,本文将探讨这样做的一些潜在问题。
让设想一个简单的计算页面,该页面可以计算两个数字的和:
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ScriptMode="Debug">
<Scripts>
<asp:ScriptReference Path="~/jquery-1.2.6.debug.js" />
</Scripts>
</asp:ScriptManager>
<asp:UpdatePanel ID="up" runat="server">
<ContentTemplate>
<asp:TextBox ID="i1" runat="server" CssClass="num" Width="50px" />
+ <asp:TextBox ID="i2" runat="server" CssClass="num" Width="50px" />
= <asp:TextBox ID="res" runat="server" Width="50px" />
<asp:Button ID="btn" runat="server" Text="..." />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
页面包含ScriptManager和jQuery脚本。定义了三个输入控件,前两个具有class='num',以便可以使用jQuery轻松地找到它们。内容被放置在
迭代1的方法在一段时间内对有效。但最终,注意到Internet Explorer的速度变慢了。很多。然后查看进程监视器时,注意到Internet Explorer在中等大小的表单上每次UpdatePanel刷新时都会泄漏大约1MB的内存。使用sIEve工具(感谢创建者),看到输入元素没有被销毁:
每次点击刷新时,它都会创建一组新的输入元素,而不会销毁之前的元素。
UpdatePanel提供了清理钩子。当它即将丢弃一个元素时,它会检查是否存在一个element.dispose函数。如果存在这样的函数,那么它将被执行。因此,最终创建了以下jQuery插件来处理这种情况:
(function($) {
$.fn.Disposable = function(cln) {
return this.each(function() {
var el = this;
if (!el.dispose) {
el.dispose = cleanup;
// 将由Microsoft调用清理
$(window).bind("unload", cleanup);
}
function cleanup() {
if (!el) return;
$(el).unbind();
$(window).unbind("unload", cleanup);
el.dispose = null;
el = null;
};
});
};
})(jQuery);
function add() {
$get('res').value = parseInt($get('i1').value) + parseInt($get('i2').value);
}
Sys.Application.add_load(function() {
$('.num').change(add).Disposable();
});
这个jQuery插件将一个cleanup()函数附加到element.dispose。每当element.dispose被调用时,所有的jQuery事件都将从元素中解绑,允许垃圾收集器回收所有对象。