技术开发 频道

UpdatePanel的妙用:Incremental Content

IT168技术文档】

    在UpdatePanel对页面进行部分刷新时注册一些Data Item是ASP.NET AJAX的特点之一。我们可以在服务器端为某个控件注册一个字符串甚至是一个对象,然后在客户端将将其取回。但是现在我希望向您展示一些您可能会忽视的事情。

    让我们先从最基本的用法开始。在一个异步回送过程中,我们可以调用RegisterDataItem方法将一个字符串与一个UpdatePanel绑定起来:

    RegisterDataItem方法调用
ScriptManager.GetCurrent(this.Page).RegisterDataItem(this.UpdatePanel1, "DataItem");

    在客户端,如果我们监听pageLoading,pageLoaded或者endRequest事件,我们就可以使用下面的代码,使用控件的ClientID将这个字符串取回:

    将字符串取回
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(
function(sender, e)
{
var dataItem = e.get_dataItems()["<%= this.UpdatePanel1.ClientID %>"]; // "DataItem"
// more implementations...
});

    RegisterDataItem方法还有一个重载的版本会接受一个额外的参数,其作用是使用一个布尔值来表明我们注册的dataItem是不是已经被序列化为JSON。但是这里就出了一个问题——甚至在官方文档中的示例也是不正确的。

    下面的代码选自官方文档中的示例:

    官方文档中的示例
protected void Page_Load(object sender, EventArgs e)
{
if (ScriptManager1.IsInAsyncPostBack)
{
System.Web.Script.Serialization.JavaScriptSerializer json =
new System.Web.Script.Serialization.JavaScriptSerializer();
ScriptManager1.RegisterDataItem(Label1, DateTime.Now.ToString());
ScriptManager1.RegisterDataItem(Label2, json.Serialize("more data"), true);
}
}

    这个示例的确能够正常工作,但是它事实上掩盖了一个问题。请注意,序列化之后的Data Item会被JavaScript内置的eval方法解释执行:

    使用eval函数解释执行
function Sys$WebForms$PageRequestManager$_onFormSubmitCompleted(sender, eventArgs)
{
//...

for (i = 0; i < dataItemJsonNodes.length; i++) {
var dataItemJsonNode = dataItemJsonNodes[i];
this._dataItems[dataItemJsonNode.id] = eval(dataItemJsonNode.content);
}

//...
}
    在官方文档的示例中,字符串“more data”会被序列化为“"more data"”(请注意多出的双引号),这样从eval方法中得到的结果就是“more data”,这正是我们注册的内容。这个再正常不多了,不是吗?猜猜看如果我们将一个序列化的对象注册到客户端时会发生什么事情呢?我为此写了一个示例:

    注册一个对象
// the definition of Person class
public class Person
{
public string Name;
}
// the code to register a Person object
Person person = new Person();
person.Name = "Jeffz";
JavaScriptSerializer serializer = new JavaScriptSerializer();
ScriptManager.GetCurrent(this.Page).RegisterDataItem(
this.UpdatePanel1, serializer.Serialize(person), true);

    当我们进行异步更新时就会抛出异常。似乎这是因为服务器端注册的表示Person对象的JSON字符串“{"Name":"Jeffz"}”无法被直接传递进入eval方法。具体的原因关乎语法方面的问题,可以在ECMAScript Specification中找到解释,因此我在这里就不多作解释了。那么,请注意我下面的代码:

    为JSON字符串添加括号
ScriptManager.GetCurrent(this.Page).RegisterDataItem(
this.UpdatePanel1, "(" + serializer.Serialize(person) + ")", true);

0
相关文章