Iterace č. 7 – přidání funkcí Ajax (VB)
od Microsoftu
V sedmé iteraci vylepšujeme rychlost odezvy a výkon naší aplikace přidáním podpory pro Ajax.
Vytvoření aplikace Správy kontaktů ASP.NET MVC (VB)
V této sérii kurzů sestavíme od začátku do konce celou aplikaci Pro správu kontaktů. Aplikace Contact Manager umožňuje ukládat kontaktní informace – jména, telefonní čísla a e-mailové adresy – pro seznam osob.
Aplikaci sestavíme pomocí několika iterací. S každou iterací aplikaci postupně vylepšujeme. Cílem tohoto přístupu s více iteracemi je pochopit důvod každé změny.
Iterace č. 1 – vytvořte aplikaci. V první iteraci vytvoříme Správce kontaktů nejjednodušším možným způsobem. Přidáváme podporu základních databázových operací: vytvoření, čtení, aktualizace a odstranění (CRUD).
Iterace č. 2 – vzhled aplikace V této iteraci vylepšujeme vzhled aplikace úpravou výchozí ASP.NET stránky předlohy zobrazení MVC a šablony stylů CSS.
Iterace č. 3 – přidání ověření formuláře Ve třetí iteraci přidáme základní ověření formuláře. Bráníme uživatelům v odeslání formuláře bez vyplnění požadovaných polí formuláře. Ověřujeme také e-mailové adresy a telefonní čísla.
Iterace č. 4 – Nastavte aplikaci volně na párování. V této čtvrté iteraci využijeme několik vzorů návrhu softwaru, které usnadňují údržbu a úpravy aplikace Contact Manager. Například refaktorujeme aplikaci tak, aby používala vzor úložiště a model injektáže závislostí.
Iterace č. 5 – vytvoření testů jednotek V páté iteraci usnadňujeme údržbu a úpravy naší aplikace přidáním testů jednotek. Vysmíváme si třídy datového modelu a sestavujeme testy jednotek pro naše kontrolery a logiku ověřování.
Iterace č. 6 – použijte vývoj řízený testy. V této šesté iteraci přidáme do naší aplikace nové funkce tím, že nejprve napíšeme testy jednotek a proti testům jednotek napíšeme kód. V této iteraci přidáme skupiny kontaktů.
Iterace č. 7 – přidání funkcí Ajax V sedmé iteraci vylepšujeme rychlost odezvy a výkon naší aplikace přidáním podpory pro Ajax.
Tato iterace
V této iteraci aplikace Contact Manager refaktorujeme aplikaci tak, aby využívala ajax. Díky využití ajaxu je naše aplikace lépe responzivní. Můžeme se vyhnout vykreslování celé stránky, když potřebujeme aktualizovat jenom určitou oblast na stránce.
Refaktorujeme zobrazení Index, abychom nemuseli znovu zobrazovat celou stránku, kdykoli někdo vybere novou skupinu kontaktů. Místo toho, když někdo klikne na skupinu kontaktů, aktualizujeme seznam kontaktů a zbytek stránky necháme být.
Změníme také způsob, jakým odkaz na odstranění funguje. Místo zobrazení samostatné potvrzovací stránky se zobrazí potvrzovací dialogové okno JavaScriptu. Pokud potvrdíte, že chcete kontakt odstranit, provede se se serverem operace HTTP DELETE, která odstraní záznam kontaktu z databáze.
Kromě toho využijeme jQuery k přidání animačních efektů do zobrazení Index. Když se nový seznam kontaktů načítá ze serveru, zobrazíme animaci.
Nakonec využijeme podporu rozhraní ASP.NET AJAX pro správu historie prohlížeče. Body historie vytvoříme vždy, když provedeme volání Ajaxu pro aktualizaci seznamu kontaktů. Tímto způsobem budou fungovat tlačítka zpět a vpřed v prohlížeči.
Proč používat Ajax?
Používání ajaxu má mnoho výhod. Za prvé, přidání funkcí Ajax do aplikace vede k lepšímu uživatelskému prostředí. V normální webové aplikaci musí být celá stránka odeslána zpět na server pokaždé, když uživatel provede nějakou akci. Při každém provedení akce se prohlížeč uzamkne a uživatel musí počkat, až se načte a znovu zobrazí celá stránka.
V případě desktopové aplikace by to bylo nepřijatelné. Tradičně jsme ale žili s tímto špatným uživatelským prostředím v případě webové aplikace, protože jsme nevěděli, že bychom to mohli udělat lépe. Mysleli jsme si, že jde o omezení webových aplikací, i když ve skutečnosti šlo jen o omezení naší představivosti.
V aplikaci Ajax není nutné zastavit uživatelské prostředí jen kvůli aktualizaci stránky. Místo toho můžete provést asynchronní požadavek na aktualizaci stránky na pozadí. Nenutíte uživatele čekat na aktualizaci části stránky.
Když využijete ajax, můžete také zlepšit výkon vaší aplikace. Zamyslete se nad tím, jak aplikace Contact Manager funguje bez funkcí Ajax. Když kliknete na skupinu kontaktů, musí se znovu zobrazit celé zobrazení indexu. Seznam kontaktů a seznam skupin kontaktů se musí načíst z databázového serveru. Všechna tato data se musí předávat z webového serveru do webového prohlížeče.
Po přidání funkcí Ajax do naší aplikace se ale můžeme vyhnout opakovanému zobrazení celé stránky, když uživatel klikne na skupinu kontaktů. Skupiny kontaktů už nemusíme z databáze zachytávat. Také nemusíme tlačit celé zobrazení indexu přes kabel. Využitím ajaxu snížíme množství práce, kterou musí náš databázový server provést, a snížíme objem síťového provozu vyžadovaného naší aplikací.
Nebojte se Ajaxu
Někteří vývojáři se používání ajaxu vyhýbají, protože mají obavy z prohlížečů nižší úrovně. Chtějí mít jistotu, že jejich webové aplikace budou fungovat i při přístupu z prohlížeče, který nepodporuje JavaScript. Protože Ajax závisí na JavaScriptu, někteří vývojáři se mu vyhýbají.
Pokud jste však opatrní při implementaci Ajax, můžete vytvářet aplikace, které pracují s prohlížeči na nejvyšší i nižší úrovni. Naše aplikace Contact Manager bude fungovat s prohlížeči, které podporují JavaScript, i s prohlížeči, které ho nepodporují.
Pokud používáte aplikaci Contact Manager s prohlížečem, který podporuje JavaScript, budete mít lepší uživatelské prostředí. Když například kliknete na skupinu kontaktů, aktualizuje se jenom oblast stránky, na které se zobrazují kontakty.
Pokud na druhou stranu používáte aplikaci Contact Manager s prohlížečem, který nepodporuje JavaScript (nebo má JavaScript zakázaný), budete mít trochu méně žádoucí uživatelské prostředí. Když například kliknete na skupinu kontaktů, musí být celé zobrazení indexu odesláno zpět do prohlížeče, aby se zobrazil odpovídající seznam kontaktů.
Přidání požadovaných souborů JavaScriptu
K přidání funkcí Ajax do naší aplikace budeme muset použít tři soubory JavaScriptu. Všechny tři tyto soubory jsou součástí složky Scripts nové aplikace ASP.NET MVC.
Pokud plánujete používat Ajax na více stránkách aplikace, je vhodné zahrnout požadované soubory JavaScriptu do stránky předlohy zobrazení aplikace. Soubory JavaScriptu se tak automaticky zahrnou do všech stránek vaší aplikace.
Do značky head> stránky předlohy zobrazení přidejte následující kód JavaScriptu<:
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-1.2.6.min.js" type="text/javascript"></script>
Refaktoring zobrazení indexu tak, aby používalo Ajax
Začněme úpravou zobrazení indexu tak, aby se kliknutím na skupinu kontaktů aktualizovala jenom oblast zobrazení, ve které se zobrazují kontakty. Červené pole na obrázku 1 obsahuje oblast, kterou chceme aktualizovat.
Obrázek 01: Aktualizace jenom kontaktů (kliknutím zobrazíte obrázek v plné velikosti)
Prvním krokem je rozdělení části zobrazení, kterou chceme asynchronně aktualizovat, na samostatnou část (zobrazení uživatelského ovládacího prvku). Část zobrazení Index, která zobrazuje tabulku kontaktů, byla přesunuta do části v seznamu 1.
Výpis 1 – Views\Contact\ContactList.ascx
<%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl(Of ContactManager.Group)" %>
<table class="data-table" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th class="actions edit">
Edit
</th>
<th class="actions delete">
Delete
</th>
<th>
Name
</th>
<th>
Phone
</th>
<th>
Email
</th>
</tr>
</thead>
<tbody>
<% For Each item in Model.Contacts %>
<tr>
<td class="actions edit">
<a href='<%= Url.Action("Edit", New With {.id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
</td>
<td class="actions delete">
<a href='<%= Url.Action("Delete", New With {.id=item.Id}) %>'><img src="../../Content/Delete.png" alt="Delete" /></a>
</td>
<th>
<%= Html.Encode(item.FirstName) %>
<%= Html.Encode(item.LastName) %>
</th>
<td>
<%= Html.Encode(item.Phone) %>
</td>
<td>
<%= Html.Encode(item.Email) %>
</td>
</tr>
<% Next %>
</tbody>
</table>
Všimněte si, že část v výpisu 1 má jiný model než zobrazení indexu. Inherits atribut v <%@ Page %> direktiva určuje, že částečná dědí z ViewUserControl<Group třídy>.
Aktualizované zobrazení indexu je obsaženo ve výpisu 2.
Výpis 2 – Views\Contact\Index.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of ContactManager.IndexModel)" %>
<%@ Import Namespace="ContactManager" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<ul id="leftColumn">
<% For Each item in Model.Groups %>
<li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
<%= Ajax.ActionLink(item.Name, "Index", New With { .id = item.Id }, New AjaxOptions With { .UpdateTargetId = "divContactList"})%>
</li>
<% Next %>
</ul>
<div id="divContactList">
<% Html.RenderPartial("ContactList", Model.SelectedGroup) %>
</div>
<div class="divContactList-bottom"> </div>
</asp:Content>
U aktualizovaného zobrazení v seznamu 2 byste si měli všimnout dvou věcí. Nejprve si všimněte, že veškerý obsah přesunutý do části je nahrazen voláním Html.RenderPartial(). Html.RenderPartial() Metoda je volána při zobrazení indexu je poprvé požadována, aby se zobrazila počáteční sada kontaktů.
Za druhé si všimněte, že html.ActionLink() použitý k zobrazení skupin kontaktů byl nahrazen řetězcem Ajax.ActionLink(). Ajax.ActionLink() se volá s následujícími parametry:
<%= Ajax.ActionLink(item.Name, "Index", New With { .id = item.Id }, New AjaxOptions With { .UpdateTargetId = "divContactList"})%>
První parametr představuje text, který se má zobrazit pro odkaz, druhý parametr představuje hodnoty trasy a třetí parametr představuje možnosti Ajax. V tomto případě použijeme možnost UpdateTargetId Ajax k odkazování na značku div> HTML<, kterou chceme aktualizovat po dokončení požadavku Ajax. Chceme aktualizovat <značku div> novým seznamem kontaktů.
Aktualizovaná metoda Index() kontroleru kontaktu je obsažena v výpisu 3.
Výpis 3 – Controllers\ContactController.vb (indexová metoda)
Public Function Index(ByVal id As Integer?) As ActionResult
' Get selected group
Dim selectedGroup = _service.GetGroup(id)
if IsNothing(selectedGroup) Then
Return RedirectToAction("Index", "Group")
End If
' Normal Request
if Not Request.IsAjaxRequest() Then
Dim model As new IndexModel With { _
.Groups = _service.ListGroups(), _
.SelectedGroup = selectedGroup _
}
Return View("Index", model)
End If
' Ajax Request
return PartialView("ContactList", selectedGroup)
End Function
Aktualizovaná akce Index() podmíněně vrátí jednu ze dvou věcí. Pokud je akci Index() vyvolána požadavkem Ajax, vrátí kontroler částečnou hodnotu. V opačném případě vrátí akce Index() celé zobrazení.
Všimněte si, že akce Index() nemusí při vyvolání požadavkem Ajax vracet tolik dat. V kontextu normálního požadavku vrátí akce Index seznam všech skupin kontaktů a vybrané skupiny kontaktů. V kontextu požadavku Ajax vrátí akce Index() pouze vybranou skupinu. Ajax znamená méně práce na databázovém serveru.
Upravené zobrazení indexu funguje v případě prohlížečů na nejvyšší i nižší úrovni. Pokud kliknete na skupinu kontaktů a prohlížeč podporuje JavaScript, aktualizuje se jenom oblast zobrazení, která obsahuje seznam kontaktů. Pokud naopak váš prohlížeč nepodporuje JavaScript, celé zobrazení se aktualizuje.
Naše aktualizované zobrazení indexu má jeden problém. Když kliknete na skupinu kontaktů, vybraná skupina se nezvýrazní. Vzhledem k tomu, že seznam skupin se zobrazuje mimo oblast, která se aktualizuje během požadavku Ajax, nezvýrazní se správná skupina. Tento problém vyřešíme v další části.
Přidání animačních efektů jQuery
Když kliknete na odkaz na webové stránce, můžete obvykle pomocí indikátoru průběhu prohlížeče zjistit, jestli prohlížeč aktivně načítá aktualizovaný obsah. Při provádění požadavku Ajax naopak indikátor průběhu prohlížeče nezobrazuje žádný průběh. To může uživatele znervóznit. Jak zjistíte, jestli se prohlížeč zamrznul?
Existuje několik způsobů, jak můžete uživateli označit, že se při provádění požadavku Ajax provádí práce. Jedním z přístupů je zobrazení jednoduché animace. Můžete například zeslabit oblast, když začne požadavek Ajax, a po dokončení požadavku v této oblasti zeslábnout.
K vytvoření animačních efektů použijeme knihovnu jQuery, která je součástí architektury Microsoft ASP.NET MVC. Aktualizované zobrazení indexu je obsaženo ve výpisu 4.
Výpis 4 – Views\Contact\Index.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of ContactManager.IndexModel)" %>
<%@ Import Namespace="ContactManager" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
function beginContactList(args)
{
// Highlight selected group
$('#leftColumn li').removeClass('selected');
$(this).parent().addClass('selected');
// Animate
$('#divContactList').fadeOut('normal');
}
function successContactList()
{
// Animate
$('#divContactList').fadeIn('normal');
}
function failureContactList()
{
alert("Could not retrieve contacts.");
}
</script>
<ul id="leftColumn">
<% For Each item in Model.Groups %>
<li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
<%= Ajax.ActionLink(item.Name, "Index", New With { .id = item.Id }, New AjaxOptions With { .UpdateTargetId = "divContactList", .OnBegin = "beginContactList", .OnSuccess = "successContactList", .OnFailure = "failureContactList" })%>
</li>
<% Next %>
</ul>
<div id="divContactList">
<% Html.RenderPartial("ContactList", Model.SelectedGroup) %>
</div>
<div class="divContactList-bottom"> </div>
</asp:Content>
Všimněte si, že aktualizované zobrazení Index obsahuje tři nové javascriptové funkce. První dvě funkce používají jQuery, aby po kliknutí na novou skupinu kontaktů zeslábnul a zeslábnul v seznamu kontaktů. Třetí funkce zobrazí chybovou zprávu, když výsledkem požadavku Ajax je chyba (například vypršení časového limitu sítě).
První funkce se také postará o zvýraznění vybrané skupiny. Do nadřazeného elementu (element LI) kliknutí elementu se přidá atribut class= vybraný atribut. JQuery opět usnadňuje výběr správného prvku a přidání třídy CSS.
Tyto skripty jsou svázány se skupinovými odkazy pomocí parametru Ajax.ActionLink() AjaxOptions. Aktualizované volání metody Ajax.ActionLink() vypadá takto:
<%= Ajax.ActionLink(item.Name, "Index", New With { .id = item.Id }, New AjaxOptions With { .UpdateTargetId = "divContactList", .OnBegin = "beginContactList", .OnSuccess = "successContactList", .OnFailure = "failureContactList" })%>
Přidání podpory historie prohlížeče
Když kliknete na odkaz pro aktualizaci stránky, obvykle se aktualizuje historie prohlížeče. Tímto způsobem můžete kliknutím na tlačítko Zpět v prohlížeči přejít zpět v čase do předchozího stavu stránky. Pokud například kliknete na skupinu kontaktů Přátelé a potom kliknete na skupinu obchodních kontaktů, můžete kliknutím na tlačítko Zpět v prohlížeči přejít zpět do stavu stránky, kdy byla vybrána skupina kontaktů Přátelé.
Provedení požadavku Ajax bohužel neaktualizuje historii prohlížeče automaticky. Pokud kliknete na skupinu kontaktů a seznam odpovídajících kontaktů se načte s požadavkem Ajax, historie prohlížeče se neaktualizuje. Tlačítko Zpět v prohlížeči nelze použít k přechodu zpět do skupiny kontaktů po výběru nové skupiny kontaktů.
Pokud chcete, aby uživatelé mohli používat tlačítko Zpět v prohlížeči po provedení požadavků Ajax, musíte provést trochu více práce. Potřebujete využít funkci správy historie prohlížeče integrovanou v rozhraní ASP.NET AJAX Framework.
ASP.NET historii prohlížeče AJAX je potřeba udělat tři věci:
- Povolte historii prohlížeče nastavením vlastnosti enableBrowserHistory na true.
- Pokud se změní stav zobrazení, uložte body historie voláním metody addHistoryPoint().
- Rekonstruujte stav zobrazení při vyvolání události navigate.
Aktualizované zobrazení indexu je obsaženo ve výpisu 5.
Výpis 5 – Views\Contact\Index.aspx
<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of ContactManager.IndexModel)" %>
<%@ Import Namespace="ContactManager" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
var _currentGroupId = -1;
Sys.Application.add_init(pageInit);
function pageInit() {
// Enable history
Sys.Application.set_enableHistory(true);
// Add Handler for history
Sys.Application.add_navigate(navigate);
}
function navigate(sender, e) {
// Get groupId from address bar
var groupId = e.get_state().groupId;
// If groupId != currentGroupId then navigate
if (groupId != _currentGroupId) {
_currentGroupId = groupId;
$("#divContactList").load("/Contact/Index/" + groupId);
selectGroup(groupId);
}
}
function selectGroup(groupId) {
$('#leftColumn li').removeClass('selected');
if (groupId)
$('a[groupid=' + groupId + ']').parent().addClass('selected');
else
$('#leftColumn li:first').addClass('selected');
}
function beginContactList(args) {
// Highlight selected group
_currentGroupId = this.getAttribute("groupid");
selectGroup(_currentGroupId);
// Add history point
Sys.Application.addHistoryPoint({ "groupId": _currentGroupId });
// Animate
$('#divContactList').fadeOut('normal');
}
function successContactList() {
// Animate
$('#divContactList').fadeIn('normal');
}
function failureContactList() {
alert("Could not retrieve contacts.");
}
</script>
<ul id="leftColumn">
<% For Each item in Model.Groups %>
<li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
<%= Ajax.ActionLink(item.Name, "Index", New With { .id = item.Id }, New AjaxOptions With { .UpdateTargetId = "divContactList", .OnBegin = "beginContactList", .OnSuccess = "successContactList", .OnFailure = "failureContactList" }, New With { .groupid = item.Id })%>
</li>
<% Next %>
</ul>
<div id="divContactList">
<% Html.RenderPartial("ContactList", Model.SelectedGroup) %>
</div>
<div class="divContactList-bottom"> </div>
</asp:Content>
Ve výpisu 5 je ve funkci pageInit() povolená historie prohlížeče. Funkce pageInit() se také používá k nastavení obslužné rutiny události pro událost navigate. Událost navigate se vyvolá vždy, když se změní stav stránky pomocí tlačítka Vpřed nebo Zpět v prohlížeči.
Metoda beginContactList() je volána při kliknutí na skupinu kontaktů. Tato metoda vytvoří nový bod historie voláním metody addHistoryPoint(). ID skupiny kontaktů, na kterou jste klikli, se přidá do historie.
ID skupiny se načte z atributu expando na odkazu na skupinu kontaktů. Odkaz se vykreslí s následujícím voláním Ajax.ActionLink().
<%= Ajax.ActionLink(item.Name, "Index", New With { .id = item.Id }, New AjaxOptions With { .UpdateTargetId = "divContactList", .OnBegin = "beginContactList", .OnSuccess = "successContactList", .OnFailure = "failureContactList" }, New With { .groupid = item.Id })%>
Poslední parametr předaný ajax.ActionLink() přidá do odkazu atribut expando s názvem groupid (pro kompatibilitu XHTML malými písmeny).
Když uživatel narazí na tlačítko Zpět nebo Vpřed v prohlížeči, vyvolá se událost navigate a zavolá se metoda navigate(). Tato metoda aktualizuje kontakty zobrazené na stránce tak, aby odpovídaly stavu stránky, který odpovídá bodu historie prohlížeče předaného metodě navigate.
Provádění odstranění Ajax
Pokud chcete odstranit kontakt, musíte v současné době kliknout na odkaz Odstranit a potom kliknout na tlačítko Odstranit zobrazené na stránce potvrzení odstranění (viz obrázek 2). Zdá se, že se jedná o spoustu požadavků na stránku, které mají udělat něco jednoduchého, jako je odstranění záznamu databáze.
Obrázek 02: Stránka potvrzení odstranění (kliknutím zobrazíte obrázek v plné velikosti)
Je lákavé přeskočit stránku potvrzení odstranění a odstranit kontakt přímo ze zobrazení indexu. Tomuto pokušení byste se měli vyhnout, protože tento přístup otevře vaši aplikaci bezpečnostním dírám. Obecně platí, že při vyvolání akce, která mění stav webové aplikace, nechcete provádět operaci HTTP GET. Při provádění odstranění chcete provést operaci HTTP POST, nebo ještě lépe operaci HTTP DELETE.
Odkaz Odstranit je obsažen v části ContactList. Aktualizovaná verze částečného seznamu kontaktů je obsažena v seznamu 6.
Výpis 6 – Views\Contact\ContactList.ascx
<%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl(Of ContactManager.Group)" %>
<%@ Import Namespace="ContactManager" %>
<table class="data-table" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th class="actions edit">
Edit
</th>
<th class="actions delete">
Delete
</th>
<th>
Name
</th>
<th>
Phone
</th>
<th>
Email
</th>
</tr>
</thead>
<tbody>
<% For Each item in Model.Contacts %>
<tr>
<td class="actions edit">
<a href='<%= Url.Action("Edit", New With {.id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
</td>
<td class="actions delete">
<%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", New with { .id = item.Id }, New AjaxOptions With { .Confirm = "Delete contact?", .HttpMethod = "Delete", .UpdateTargetId = "divContactList" })%>
</td>
<th>
<%= Html.Encode(item.FirstName) %>
<%= Html.Encode(item.LastName) %>
</th>
<td>
<%= Html.Encode(item.Phone) %>
</td>
<td>
<%= Html.Encode(item.Email) %>
</td>
</tr>
<% Next %>
</tbody>
</table>
Odkaz Delete se vykreslí s následujícím voláním metody Ajax.ImageActionLink():
<%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", New with { .id = item.Id }, New AjaxOptions With { .Confirm = "Delete contact?", .HttpMethod = "Delete", .UpdateTargetId = "divContactList" })%<
Poznámka
Ajax.ImageActionLink() není standardní součástí architektury ASP.NET MVC. Ajax.ImageActionLink() je vlastní pomocné metody zahrnuté v projektu Contact Manager.
Parametr AjaxOptions má dvě vlastnosti. Nejprve se vlastnost Confirm použije k zobrazení automaticky otevírané dialogové okno potvrzení JavaScriptu. Za druhé, HttpMethod vlastnost se používá k provedení operace HTTP DELETE.
Výpis 7 obsahuje novou akci AjaxDelete(), která byla přidána do kontroleru kontaktu.
Výpis 7 – Controllers\ContactController.vb (AjaxDelete)
<AcceptVerbs(HttpVerbs.Delete), ActionName("Delete")> _
Public Function AjaxDelete(ByVal id As Integer) As ActionResult
' Get contact and group
Dim contactToDelete = _service.GetContact(id)
Dim selectedGroup = _service.GetGroup(contactToDelete.Group.Id)
' Delete from database
_service.DeleteContact(contactToDelete)
' Return Contact List
Return PartialView("ContactList", selectedGroup)
End Function
Akce AjaxDelete() je zdobena atributem AcceptVerbs. Tento atribut brání vyvolání akce s výjimkou jakékoli jiné operace HTTP než operace HTTP DELETE. Konkrétně nelze vyvolat tuto akci pomocí http GET.
Po odstranění záznamu databáze musíte zobrazit aktualizovaný seznam kontaktů, které odstraněný záznam neobsahují. Metoda AjaxDelete() vrátí část ContactList a aktualizovaný seznam kontaktů.
Souhrn
V této iteraci jsme do aplikace Contact Manager přidali funkci Ajax. Ajax jsme použili ke zlepšení odezvy a výkonu naší aplikace.
Nejprve jsme refaktorovali zobrazení Index, aby se kliknutím na skupinu kontaktů neaktualizuje celé zobrazení. Místo toho kliknutím na skupinu kontaktů aktualizujete jenom seznam kontaktů.
Dále jsme použili animační efekty jQuery k vyblednutí a vyblednutí v seznamu kontaktů. Přidáním animace do aplikace Ajax můžete uživatelům aplikace poskytnout ekvivalent indikátoru průběhu prohlížeče.
Do naší aplikace Ajax jsme také přidali podporu historie prohlížeče. Povolili jsme uživatelům, aby kliknutím na tlačítka Zpět a Vpřed v prohlížeči změnili stav zobrazení indexu.
Nakonec jsme vytvořili odkaz pro odstranění, který podporuje operace HTTP DELETE. Prováděním odstranění Ajax umožňujeme uživatelům odstranit databázové záznamy, aniž by uživatel musel požádat o další stránku potvrzení odstranění.