Iterace č. 7– přidání funkcí Ajax (C#)
od Microsoftu
V sedmé iteraci vylepšujeme rychlost odezvy a výkon naší aplikace přidáním podpory pro Ajax.
Sestavení aplikace Správy kontaktů ASP.NET MVC (C#)
V této sérii kurzů sestavíme celou aplikaci Pro správu kontaktů od začátku do konce. Aplikace Contact Manager umožňuje ukládat kontaktní informace – jména, telefonní čísla a e-mailové adresy – pro seznam lidí.
Aplikaci sestavíme pomocí několika iterací. S každou iterací aplikaci postupně vylepšujeme. Cílem tohoto přístupu k vícenásobné iteraci 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 pro základní databázové operace: vytvoření, čtení, aktualizace a odstranění (CRUD).
Iterace č. 2 – aby aplikace vypadala hezky. V této iteraci vylepšujeme vzhled aplikace úpravou výchozí stránky předlohy zobrazení ASP.NET zobrazení MVC a šablony stylů CSS.
Iterace č. 3 – přidejte ověření formuláře. Ve třetí iteraci přidáme základní ověření formuláře. Bráníme uživatelům v odesílá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ě provázanou. V této čtvrté iteraci využijeme několik vzorů návrhu softwaru, abychom usnadnili údržbu a úpravu aplikace Contact Manager. Například refaktorujeme aplikaci tak, aby používala vzor Úložiště a injektáž 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. Napodobení tříd datového modelu a sestavení testů 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 napíšeme kód proti testům jednotek. 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í. Pokud potřebujeme aktualizovat jenom určitou oblast stránky, můžeme se vyhnout vykreslování celé stránky.
Refaktorujeme zobrazení indexu, abychom nemuseli znovu zobrazovat celou stránku pokaždé, když někdo vybere novou skupinu kontaktů. Když někdo klikne na skupinu kontaktů, jenom aktualizujeme seznam kontaktů a necháme zbytek stránky na pokoji.
Změníme také způsob, jakým odkaz na odstranění funguje. Místo zobrazení samostatné potvrzovací stránky zobrazíme potvrzovací dialogové okno JavaScriptu. Pokud potvrdíte, že chcete odstranit kontakt, provede se na serveru 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. Při načítání nového seznamu kontaktů ze serveru zobrazíme animaci.
Nakonec využijeme podporu architektury AJAX ASP.NET pro správu historie prohlížeče. Body historie vytvoříme pokaždé, když provedeme volání Ajax, abychom aktualizovali seznam kontaktů. Tímto způsobem budou fungovat tlačítka prohlížeče zpět a vpřed.
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é a pokaždé, když uživatel provede nějakou akci. Při každém provedení akce se prohlížeč zamkne 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é. Ale tradičně jsme ž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 mohli udělat něco lepšího. Mysleli jsme si, že jde o omezení webových aplikací, když ve skutečnosti šlo jen o omezení našich představ.
V aplikaci Ajax není nutné zastavit uživatelské prostředí jen kvůli aktualizaci stránky. Místo toho můžete na pozadí provést asynchronní požadavek na aktualizaci stránky. 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 momentálně 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 zachytávat z databáze. Také nemusíme tlačit celé zobrazení indexu přes kabel. Využitím ajaxu snižujeme množství práce, kterou musí náš databázový server provádět, a snižujeme 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 i nadále fungovat, když k nim přistupuje prohlížeč, který nepodporuje JavaScript. Vzhledem k tomu, že Ajax závisí na JavaScriptu, někteří vývojáři se používání ajaxu 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, a prohlížeči, které ne.
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 naopak používáte aplikaci Contact Manager s prohlížečem, který nepodporuje JavaScript (nebo který 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 máte v aplikaci v úmyslu používat Ajax na více stránkách, 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í javascriptové prvky<:
<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 na použití 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 oddělení části zobrazení, kterou chceme asynchronně aktualizovat, na samostatnou část (uživatelský ovládací prvek zobrazení). Část zobrazení Index, která zobrazuje tabulku kontaktů, byla přesunuta do části v seznamu 1.
Výpis 1 – Views\Contact\ContactList.ascx
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactManager.Models.Group>" %>
<%@ Import Namespace="Helpers" %>
<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>
<% foreach (var item in Model.Contacts)
{ %>
<tr>
<td class="actions edit">
<a href='<%= Url.Action("Edit", new {id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
</td>
<td class="actions delete">
<a href='<%= Url.Action("Delete", new {id=item.Id}) %>'><img src="../../Content/Delete.png" alt="Edit" /></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>
<% } %>
</tbody>
</table>
Všimněte si, že část v seznamu 1 má jiný model než zobrazení Index. Atribut Inherits v direktivě <%@ Page %> určuje, že část dědí z třídy ViewUserControl<Group>.
Aktualizované zobrazení indexu je obsaženo ve výpisu 2.
Výpis 2 – Views\Contact\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<ul id="leftColumn">
<% foreach (var item in Model.Groups) { %>
<li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList"})%>
</li>
<% } %>
</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(). Metoda Html.RenderPartial() je volána při prvním požadavku zobrazení indexu, 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 ajax.ActionLink(). Ajax.ActionLink() se volá s následujícími parametry:
<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { 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 ve výpisu 3.
Výpis 3 – Controllers\ContactController.cs (metoda indexu)
public ActionResult Index(int? id)
{
// Get selected group
var selectedGroup = _service.GetGroup(id);
if (selectedGroup == null)
return RedirectToAction("Index", "Group");
// Normal Request
if (!Request.IsAjaxRequest())
{
var model = new IndexModel
{
Groups = _service.ListGroups(),
SelectedGroup = selectedGroup
};
return View("Index", model);
}
// Ajax Request
return PartialView("ContactList", selectedGroup);
}
Aktualizovaná akce Index() podmíněně vrátí jednu ze dvou věcí. Pokud akci Index() vyvolá požadavek 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í vracet tolik dat, pokud je vyvolána požadavkem Ajax. 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 váš prohlížeč na druhou stranu 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 opraví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 pozná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 zeslatit oblast při zahájení požadavku Ajax a zeslabnout oblast po dokončení žádosti.
K vytvoření animačních efektů použijeme knihovnu jQuery, která je součástí architektury Microsoft ASP.NET MVC. Aktualizované zobrazení indexu je součástí výpisu 4.
Výpis 4 – Views\Contact\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<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">
<% foreach (var item in Model.Groups) { %>
<li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>
</li>
<% } %>
</ul>
<div id="divContactList">
<% Html.RenderPartial("ContactList", Model.SelectedGroup); %>
</div>
<div class="divContactList-bottom"> </div>
</asp:Content>
Všimněte si, že aktualizované zobrazení indexu obsahuje tři nové funkce Jazyka JavaScript. První dvě funkce po kliknutí na novou skupinu kontaktů používají jQuery k postupnému zeslabování a zesvětlení seznamu kontaktů. Třetí funkce zobrazí chybovou zprávu, když požadavek Ajax způsobí chybu (například vypršení časového limitu sítě).
První funkce se také postará o zvýraznění vybrané skupiny. Atribut class= selected je přidán do nadřazeného elementu (element LI) prvku, na který jste klikli. 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 { id = item.Id }, new AjaxOptions { 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. Díky tomu se můžete kliknutím na tlačítko Zpět v prohlížeči vrátit do předchozího stavu stránky. Pokud například kliknete na skupinu kontaktů Přátelé a potom 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, ve které 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 nejde 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 musíte udělat tři věci:
- Povolte historii prohlížeče nastavením vlastnosti enableBrowserHistory na true.
- Uložte body historie při změně stavu zobrazení voláním metody addHistoryPoint().
- Rekonstruujte stav zobrazení při vyvolání události navigace.
Aktualizované zobrazení indexu je součástí výpisu 5.
Výpis 5 – Views\Contact\Index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<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">
<% foreach (var item in Model.Groups) { %>
<li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" }, new { groupid = item.Id })%>
</li>
<% } %>
</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á pokaždé, když tlačítko Vpřed nebo Zpět v prohlížeči způsobí změnu stavu stránky.
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 { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" }, new {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
V současné době je potřeba, abyste kontakt odstranili, kliknout na odkaz Odstranit a potom kliknout na tlačítko Odstranit zobrazené na potvrzovací stránce odstranění (viz Obrázek 2). Zdá se, že se jedná o spoustu požadavků na stránku, aby se udělalo 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írá aplikaci do bezpečnostních děr. Obecně platí, že při vyvolání akce, která mění stav webové aplikace, nechcete provádět operaci HTTP GET. Při odstraňová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="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactManager.Models.Group>" %>
<%@ Import Namespace="Helpers" %>
<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>
<% foreach (var item in Model.Contacts)
{ %>
<tr>
<td class="actions edit">
<a href='<%= Url.Action("Edit", new {id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
</td>
<td class="actions delete">
<%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { 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>
<% } %>
</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 { id = item.Id }, new AjaxOptions { 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é potvrzovací dialogové okno 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.cs (AjaxDelete)
[AcceptVerbs(HttpVerbs.Delete)]
[ActionName("Delete")]
public ActionResult AjaxDelete(int id)
{
// Get contact and group
var contactToDelete = _service.GetContact(id);
var selectedGroup = _service.GetGroup(contactToDelete.Group.Id);
// Delete from database
_service.DeleteContact(contactToDelete);
// Return Contact List
return PartialView("ContactList", selectedGroup);
}
Akce AjaxDelete() je opatřena atributem AcceptVerbs. Tento atribut brání vyvolání akce s výjimkou jakékoli jiné operace HTTP než operace HTTP DELETE. Konkrétně nelze tuto akci vyvolat pomocí příkazu HTTP GET.
Po odstranění záznamu databáze musíte zobrazit aktualizovaný seznam kontaktů, který odstraněný záznam neobsahuje. 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í rychlosti odezvy a výkonu naší aplikace.
Nejprve jsme refaktorovali zobrazení Index tak, 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 zeslabování a zeslabování 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. Uživatelům jsme umožnili, aby v prohlížeči klikli na tlačítka Zpět a Vpřed a 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í.