共用方式為


使用 AJAX 傳送動態更新

Microsoft提供

下載 PDF

這是免費 「NerdDinner」 應用程式 教學課程的步驟 10,逐步解說如何使用 ASP.NET MVC 1 建置小型但完整的 Web 應用程式。

步驟 10 會實作已登入使用者對 RSVP 的支援,他們有興趣參加晚餐,並使用在晚餐詳細資料頁面中整合的 Ajax 型方法。

如果您使用 ASP.NET MVC 3,建議您遵循使用MVC 3MVC 音樂市集教學課程消費者入門。

NerdDinner 步驟 10:AJAX 啟用 RSVP 接受

現在,讓我們實作登入使用者對 RSVP 的支援,讓他們有興趣參加晚餐。 我們將使用在晚餐詳細資料頁面中整合的 AJAX 型方法來啟用此功能。

指出使用者是否為 RSVP'd

使用者可以流覽 /Dinners/Details/[id] URL,以查看特定晚餐的詳細資料:

包含 Dinner 詳細資料的 Nerd Dinner 網頁螢幕擷取畫面。

Details () 巨集指令方法的實作方式如下:

//
// GET: /Dinners/Details/2

public ActionResult Details(int id) {

    Dinner dinner = dinnerRepository.GetDinner(id);

    if (dinner == null)
        return View("NotFound");
    else
        return View(dinner);
}

我們實作 RSVP 支援的第一個步驟是將 「IsUserRegistered (username) 」 協助程式方法新增至我們稍早建置的 Dinner.cs 部分類別內的 Dinner 物件) (。 此協助程式方法會根據使用者目前是否為 Dinner 的 RSVP'd,傳回 true 或 false:

public partial class Dinner {

    public bool IsUserRegistered(string userName) {
        return RSVPs.Any(r => r.AttendeeName.Equals(userName, StringComparison.InvariantCultureIgnoreCase));
    }
}

然後,我們可以將下列程式碼新增至 Details.aspx 檢視範本,以顯示適當的訊息,指出使用者是否已註冊事件:

<% if (Request.IsAuthenticated) { %>
 
    <% if (Model.IsUserRegistered(Context.User.Identity.Name)) { %>       

        <p>You are registred for this event!</p>
    
    <% } else {  %>  
    
        <p>You are not registered for this event</p>
        
    <% }  %>
    
<% } else { %>
 
    <a href="/Account/Logon">Logon</a> to RSVP for this event.

<% } %>

現在,當使用者造訪 Dinner 時,他們將會看到此訊息:

[Nerd Dinners 詳細資料] 頁面的螢幕擷取畫面,底部會顯示您為此事件註冊的訊息。

當他們造訪 Dinner 時,他們不會註冊他們會看到下列訊息:

Nerd Dinners 詳細資料頁面的螢幕擷取畫面。此事件會顯示您未註冊的訊息。

實作暫存器動作方法

現在讓我們從詳細資料頁面新增必要的功能,讓使用者能夠取得晚餐的 RSVP。

為了實作此動作,我們將以滑鼠右鍵按一下 \Controllers 目錄並選擇 [新增 > 控制器] 功能表命令,以建立新的 「RSVPController」 類別。

我們會在新的 RSVPController 類別內實作「Register」 動作方法,以接受 Dinner 的識別碼作為引數、擷取適當的 Dinner 物件、檢查登入的使用者目前是否位於已註冊的使用者清單中,以及如果未為其新增 RSVP 物件:

public class RSVPController : Controller {

    DinnerRepository dinnerRepository = new DinnerRepository();

    //
    // AJAX: /Dinners/RSVPForEvent/1

    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Register(int id) {

        Dinner dinner = dinnerRepository.GetDinner(id);

        if (!dinner.IsUserRegistered(User.Identity.Name)) {
        
            RSVP rsvp = new RSVP();
            rsvp.AttendeeName = User.Identity.Name;

            dinner.RSVPs.Add(rsvp);
            dinnerRepository.Save();
        }

        return Content("Thanks - we'll see you there!");
    }
}

請注意,上述如何傳回簡單的字串做為動作方法的輸出。 我們可以將此訊息內嵌在檢視範本中,但因為這樣小,我們只會在控制器基類上使用 Content () 協助程式方法,並傳回類似上述的字串訊息。

使用 AJAX 呼叫 RSVPForEvent 動作方法

我們將使用 AJAX 從 [詳細資料] 檢視叫用 Register 巨集指令方法。 實作這相當簡單。 首先,我們將新增兩個腳本程式庫參考:

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

第一個程式庫會參考 AJAX 用戶端腳本程式庫 ASP.NET 核心。 此檔案的大小大約為 24k (壓縮) ,且包含核心用戶端 AJAX 功能。 第二個程式庫包含與 ASP.NET MVC 內建的 AJAX 協助程式方法整合的公用程式函式, (我們很快就會使用) 。

接著,我們可以更新我們稍早新增的檢視範本程式碼,以便不要輸出「您未註冊此事件」訊息,而是轉譯推送執行 AJAX 呼叫時的連結,以叫用 RSVP 控制器上的 RSVPForEvent 巨集指令方法,以及使用者的 RSVP:

<div id="rsvpmsg">

<% if(Request.IsAuthenticated) { %>
 
    <% if(Model.IsUserRegistered(Context.User.Identity.Name)) { %>       

        <p>You are registred for this event!</p>

    <% } else { %>  
    
        <%= Ajax.ActionLink( "RSVP for this event",
                             "Register", "RSVP",
                             new { id=Model.DinnerID }, 
                             new AjaxOptions { UpdateTargetId="rsvpmsg"}) %>         
    <% } %>
    
<% } else { %>
 
    <a href="/Account/Logon">Logon</a> to RSVP for this event.

<% } %>
    
</div>

上述使用的 Ajax.ActionLink () 協助程式方法內建 ASP.NET MVC,類似于 Html.ActionLink () 協助程式方法,不同之處在于它不會執行標準導覽,而是在按一下連結時對動作方法進行 AJAX 呼叫。 上述我們在 「RSVP」 控制器上呼叫 「Register」 動作方法,並將 DinnerID 當做 「id」 參數傳遞給它。 我們傳遞的最後一個 AjaxOptions 參數表示我們想要採取動作方法傳回的內容,並在識別碼為 「rsvpmsg」 的頁面上更新 HTML < div > 元素。

現在,當使用者流覽至尚未註冊的晚餐時,他們會看到 RSVP 的連結:

底部有 [R S V P] 按鈕的 [Nerd Dinners] 頁面螢幕擷取畫面。

如果他們按一下 [適用于此事件的 RSVP] 連結,他們會對 RSVP 控制器上的 Register 動作方法進行 AJAX 呼叫,並在完成時看到更新的訊息,如下所示:

[Nerd Dinner 詳細資料] 頁面的螢幕擷取畫面,其中訊息 [感謝我們會看到您位於底部]。

進行此 AJAX 呼叫時所涉及的網路頻寬和流量實際上是輕量型的。 當使用者按一下 [RSVP for this event] 連結時,系統會對連線上如下所示的 /Dinners/Register/1 URL 提出小型 HTTP POST 網路要求:

POST /Dinners/Register/49 HTTP/1.1
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Referer: http://localhost:8080/Dinners/Details/49

而來自註冊動作方法的回應只是:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 29
Thanks - we'll see you there!

此輕量型呼叫很快速,即使透過緩慢的網路也能運作。

新增 jQuery 動畫

我們實作的 AJAX 功能運作良好且快速。 不過,有時候,使用者可能不會注意到 RSVP 連結已被新文字取代。 為了讓結果更明顯,我們可以新增簡單的動畫,以吸引更新訊息的注意力。

預設 ASP.NET MVC 專案範本包含 jQuery – 一個絕佳的 (,而且 Microsoft 也支援非常熱門) 開放原始碼 JavaScript 程式庫。 jQuery 提供許多功能,包括良好的 HTML DOM 選取和效果程式庫。

若要使用 jQuery,我們會先為其新增腳本參考。 因為我們將在網站內的各種位置內使用 jQuery,所以我們會在 Site.master 主版頁面檔案中新增腳本參考,讓所有頁面都可以使用它。

<script src="/Scripts/jQuery-1.3.2.js" type="text/javascript"></script>

使用 JQuery 撰寫的程式碼通常會使用全域 「$ () 」 JavaScript 方法,使用 CSS 選取器擷取一或多個 HTML 元素。 例如, $ (「#rsvpmsg」) 會選取任何識別碼為 rsvpmsg 的 HTML 元素,而 $ (「.something」) 會選取具有 「something」 CSS 類別名稱的所有元素。 您也可以使用選取器查詢來撰寫更進階的查詢,例如「傳回所有核取的選項按鈕」,例如: $ (「input[@type=radio][@checked]」)

選取專案之後,您可以呼叫方法以採取動作,例如隱藏它們: $ (「#rsvpmsg」) .hide () ;

在我們的 RSVP 案例中,我們將定義名為 「AnimateRSVPMessage」 的簡單 JavaScript 函式,以選取 「rsvpmsg」 < div > ,並以動畫顯示其文字內容的大小。 下列程式碼會啟動小型文字,然後將其增加超過 400 毫秒的時間範圍:

<script type="text/javascript">

    function AnimateRSVPMessage() {
        $("#rsvpmsg").animate({fontSize: "1.5em"},400);
    }

</script>

然後,我們可以透過 AjaxOptions 「OnSuccess」 事件屬性 (,將它的名稱傳遞至 Ajax.ActionLink () 協助程式方法,以在 AJAX 呼叫成功完成之後呼叫這個 JavaScript 函式) :

<%= Ajax.ActionLink( "RSVP for this event",
                     "Register", "RSVP",
                     new { id=Model.DinnerID }, 
                     new AjaxOptions { UpdateTargetId="rsvpmsg",
                                       OnSuccess="AnimateRSVPMessage"}) %>

現在,按一下 [適用于此事件的 RSVP] 連結,且 AJAX 呼叫成功完成時,傳回的內容訊息將會產生動畫效果並成長大:

[Nerd Dinners] 頁面的螢幕擷取畫面,其中 [感謝我們會看到您在底部大列印] 訊息。

除了提供 「OnSuccess」 事件之外,AjaxOptions 物件還會公開 OnBegin、OnFailure 和 OnComplete 事件,您可以處理 (以及各種其他屬性和實用選項) 。

清除 - 重構 RSVP 部分檢視

我們的詳細資料檢視範本開始稍微長一點,加班會讓您更難瞭解。 為了協助改善程式碼可讀性,讓我們藉由建立部分檢視 – RSVPStatus.ascx 來完成,以封裝我們 [詳細資料] 頁面的所有 RSVP 檢視程式碼。

我們可以在 \Views\Dinners 資料夾上按一下滑鼠右鍵,然後選擇 [新增檢 > 視] 功能表命令來執行此動作。 我們將採用 Dinner 物件作為其強型別的 ViewModel。 然後,我們可以從 Details.aspx 檢視複製/貼上 RSVP 內容。

完成此動作之後,我們也會建立另一個部分檢視 – EditAndDeleteLinks.ascx ,封裝我們的編輯和刪除連結檢視程式碼。 我們也會將 Dinner 物件當作其強型別的 ViewModel,並將 [Details.aspx] 檢視中的 [編輯] 和 [刪除] 邏輯複製/貼到其中。

然後,我們的詳細資料檢視範本可以只包含兩個 Html.RenderPartial () 方法呼叫底部:

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent"runat="server">
    <%= Html.Encode(Model.Title) %>
</asp:Content>

<asp:Content ID="details" ContentPlaceHolderID="MainContent" runat="server">

    <div id="dinnerDiv">

        <h2><%=Html.Encode(Model.Title) %></h2>
        <p>
            <strong>When:</strong> 
            <%=Model.EventDate.ToShortDateString() %> 

            <strong>@</strong>
            <%=Model.EventDate.ToShortTimeString() %>
        </p>
        <p>
            <strong>Where:</strong> 
            <%=Html.Encode(Model.Address) %>,
            <%=Html.Encode(Model.Country) %>
        </p>
         <p>
            <strong>Description:</strong> 
            <%=Html.Encode(Model.Description) %>
        </p>       
        <p>
            <strong>Organizer:</strong> 
            <%=Html.Encode(Model.HostedBy) %>
            (<%=Html.Encode(Model.ContactPhone) %>)
        </p>
    
        <% Html.RenderPartial("RSVPStatus"); %>
        <% Html.RenderPartial("EditAndDeleteLinks"); %>
 
    </div>
         
</asp:Content>

這可讓程式碼更簡潔地讀取和維護。

後續步驟

現在讓我們看看如何進一步使用 AJAX,並將互動式對應支援新增至應用程式。