天天看點

有關注冊DataItem的一些可能被忽視的事情

在UpdatePanel對頁面進行部分重新整理時注冊一些Data Item是ASP.NET AJAX的特點之一。我們可以在伺服器端為某個控件注冊一個字元串甚至是一個對象,然後在用戶端将将其取回。但是現在我希望向您展示一些您可能會忽視的事情。

  讓我們先從最基本的用法開始。在一個異步回送過程中,我們可以調用RegisterDataItem方法将一個字元串與一個UpdatePanel綁定起來:

RegisterDataItem方法調用

在用戶端,如果我們監聽pageLoading,pageLoaded或者endRequest事件,我們就可以使用下面的代碼,使用控件的ClientID将這個字元串取回:

将字元串取回

RegisterDataItem方法還有一個重載的版本會接受一個額外的參數,其作用是使用一個布爾值來表明我們注冊的dataItem是不是已經被序列化為JSON。但是這裡就出了一個問題——甚至在官方文檔中的示例也是不正确的。

  下面的代碼選自官方文檔中的示例:

官方文檔中的示例

這個示例的确能夠正常工作,但是它事實上掩蓋了一個問題。請注意,序列化之後的Data Item會被JavaScript内置的eval方法解釋執行:

使用eval函數解釋執行

在官方文檔的示例中,字元串“more data”會被序列化為“"more data"”(請注意多出的雙引号),這樣從eval方法中得到的結果就是“more data”,這正是我們注冊的内容。這個再正常不多了,不是嗎?猜猜看如果我們将一個序列化的對象注冊到用戶端時會發生什麼事情呢?我為此寫了一個示例:

注冊一個對象

為JSON字元串添加括号

現在,我們的代碼就能正常工作了,于是我們就可以在用戶端将Person對象取出:

在客戶段取出Person對象

這樣看來,這個問題也就可以使用這個方法來解決了。不過為什麼ASP.NET AJAX會使用eval方法,而不是定義在Microsoft AJAX Library中的deserialize方法來反序列化一個對象呢?我們可以發現,在deserialize方法中,一個表達式被傳遞給eval方法之前會被自動加上括号:

desrialize方法

  嗯,我們問題也看夠了,就把目光移向别處吧。盡管邏輯上一個Data Item應該是一個包含資訊的對象,但是請注意我們是使用eval方法來“反序列化”一個JSON字元串的。這意味着我們事實上可以将任意的合法表達式發送到用戶端,然後它就會被正确執行。請看下面的示例:

伺服器端代碼

用戶端代碼

我在上面代碼中将一個函數注冊為一個Data Item并且在用戶端将其執行了。如果您深入了解UpdatePanel局部重新整理的過程,您會注意到您在伺服器端注冊的JavaScript代碼隻有在頁面更新結束後才會生效,也就是說,我們無法在pageLoading事件被觸發時執行這些代碼。我會在之後的文章中針對這樣的設計以及如何使用work arounds來解決這個問題進行詳細的探讨。這些work arounds就是基于Data Item注冊的使用方式的,因為表示Data Item的“JSON字元串”在pageLoading觸發之前就被解釋執行。

本文轉自 jeffz 51CTO部落格,原文連結:http://blog.51cto.com/jeffz/59902,如需轉載請自行聯系原作者

繼續閱讀