撰寫自用的 ScriptManager 來管理用戶端指令碼

撰寫自用的 ScriptManager 來管理用戶端指令碼

摘要

一般在註冊用戶端指令碼都是使用 Page.ClientScript 屬性,不過當 ASP.NET AJAX 出來後,有使用 UpdatePanel 時就需要改用 ScriptManager 來取代部分註冊用戶端指令碼的動作。不過這樣有時要使用 ClientScript,有時要使用 ScriptManager 來管理用戶端指令碼,感覺有點麻煩。而且不知那天又會有 ASP.NET AJAX 2 跑出來,是否又會有新的 ScriptManager2,到時是不是又要改寫部分註冊用戶端指令碼的程式碼呢?

撰寫自用的 ScriptManager

當有使用 ASP.NET AJAX 時,一定要使用 ScriptManager 來註冊用戶端指令碼;可是又不能完全不用 ClientScript,因為有些方法(例如 GetPostBackEventReference 方法) 在 ScriptManager 並不提供。

所以我們要撰寫自用的 ScriptManager 來統一管理用戶端指令碼的所有方法,我們將撰寫 TBScriptManager 類別,整合原來 ClientScript 及 ScriptManager 所提供的方法,然後 BasePage 新增一個 BeeScript 屬性來操作 TBScriptManager 物件。

image

首先我們要新增 TBScriptManager 類別,建構函式需傳入 Page 物件,其中會包含 ScriptManager 有提供的方法,例如 RegisterStartupScript、RegisterClientScriptBlock ... 等方法,也會包含 ClientScript 有提供的方法,例如 GetPostBackEventReference、GetPostBackClientHyperlink ... 等方法。這裡只例舉出部分的方法,其他 ScriptManager 及 ClientScript 方法可以使用相同方式實現。

Imports System.Web.UI

''' <summary>
''' 用戶端指令碼管理。
''' </summary>
Public Class TBScriptManager
    Private FPage As System.Web.UI.Page

    ''' <summary>
    ''' 建構函式。
    ''' </summary>
    ''' <param name="Page">Page 物件。</param>
    Sub New(ByVal Page As System.Web.UI.Page)
        FPage = Page
    End Sub

    ''' <summary>
    ''' 註冊啟始用戶端指令碼。
    ''' </summary>
    ''' <param name="Key">索引鍵。</param>
    ''' <param name="Script">用戶端指令碼。</param>
    ''' <param name="AddScriptTags">表示是否加入指令碼標記。</param>
    Public Sub RegisterStartupScript(ByVal Key As String, ByVal Script As String, Optional ByVal AddScriptTags As Boolean = True)
        ScriptManager.RegisterStartupScript(FPage, FPage.GetType(), Key, Script, AddScriptTags)
    End Sub

    ''' <summary>
    ''' 註冊用戶端指令碼。
    ''' </summary>
    ''' <param name="Key">索引鍵。</param>
    ''' <param name="Script">用戶端指令碼。</param>
    ''' <param name="AddScriptTags">表示是否加入指令碼標記。</param>
    Public Sub RegisterClientScriptBlock(ByVal Key As String, ByVal Script As String, Optional ByVal AddScriptTags As Boolean = True)
        ScriptManager.RegisterClientScriptBlock(FPage, FPage.GetType, Key, Script, AddScriptTags)
    End Sub

    ''' <summary>
    ''' 註冊頁面 OnSubmit 的用戶端指令碼。
    ''' </summary>
    ''' <param name="Key">索引鍵。</param>
    ''' <param name="Script">用戶端指令碼。</param>
    Public Sub RegisterOnSubmitStatement(ByVal Key As String, ByVal Script As String)
        ScriptManager.RegisterOnSubmitStatement(FPage, FPage.GetType, Key, Script)
    End Sub

    ''' <summary>
    ''' 註冊用戶端指令碼 Include。
    ''' </summary>
    ''' <param name="Key">索引鍵。</param>
    ''' <param name="Url">用戶端指令碼 Include URL。</param>
    Public Sub RegisterClientScriptInclude(ByVal Key As String, ByVal Url As String)
        ScriptManager.RegisterClientScriptInclude(FPage, FPage.GetType, Key, Url)
    End Sub

    ''' <summary>
    ''' 取得引發 PostBack 的用戶端指令碼(其開頭附加了 javascript:)。 
    ''' </summary>
    ''' <param name="Control">控制項。</param>
    ''' <param name="Argument">參數。</param>
    ''' <param name="RegisterForEventValidation">事件是否進行驗證。</param>
    Public Function GetPostBackClientHyperlink(ByVal Control As Control, ByVal Argument As String, _
        Optional ByVal RegisterForEventValidation As Boolean = False) As String
        Return FPage.ClientScript.GetPostBackClientHyperlink(Control, Argument, RegisterForEventValidation)
    End Function

    ''' <summary>
    ''' 取得引發 PostBack 的用戶端指令碼。
    ''' </summary>
    ''' <param name="Options">定義回傳的 PostBackOptions。</param>
    ''' <param name="RegisterForEventValidation">事件是否進行驗證。</param>
    Public Function GetPostBackEventReference(ByVal Options As PostBackOptions, _
        Optional ByVal RegisterForEventValidation As Boolean = False) As String
        Return FPage.ClientScript.GetPostBackEventReference(Options, RegisterForEventValidation)
    End Function

    ''' <summary>
    ''' 取得引發 PostBack 的用戶端指令碼。
    ''' </summary>
    ''' <param name="Control">控制項。</param>
    ''' <param name="Argument">參數。</param>
    ''' <param name="RegisterForEventValidation">事件是否進行驗證。</param>
    Public Function GetPostBackEventReference(ByVal Control As Control, ByVal Argument As String, _
        ByVal RegisterForEventValidation As Boolean) As String
        Return FPage.ClientScript.GetPostBackEventReference(Control, Argument, RegisterForEventValidation)
    End Function

End Class

在 BasePage 中新增一個 BeeScript 屬性,來操作 TBScriptManager 物件。

''' <summary>
''' 頁面基礎類別。
''' </summary>
Public Class TBBasePage
    Inherits System.Web.UI.Page

    Private FBeeScrit As TBScriptManager = Nothing

    ''' <summary>
    ''' 用戶端指令碼管理。
    ''' </summary>
    Public ReadOnly Property BeeScript() As TBScriptManager
        Get
            If FBeeScrit Is Nothing Then
                FBeeScrit = New TBScriptManager(Me)
            End If
            Return FBeeScrit
        End Get
    End Property

End Class

若你想讓開發人員一樣可以保有使用 ClientScript 的習慣,但其背後已經是使用 TBScriptManager 物件,那就狠一點直接使用 Shadows 遮蔽掉 ClientScript 屬性,讓他們完全用不到舊的 ClientScript 屬性。

    Public Shadows ReadOnly Property ClientScript() As TBScriptManager
        Get
            If FBeeScrit Is Nothing Then
                FBeeScrit = New TBScriptManager(Me)
            End If
            Return FBeeScrit
        End Get
    End Property

ASP.NET 魔法學院