Iteração nº 7 – adicionar funcionalidade do Ajax (C#)
pela Microsoft
Na sétima iteração, melhoramos a capacidade de resposta e o desempenho de nosso aplicativo adicionando suporte ao Ajax.
Criando um aplicativo de gerenciamento de contatos ASP.NET MVC (C#)
Nesta série de tutoriais, criamos um aplicativo de Gerenciamento de Contatos inteiro do início ao fim. O aplicativo Gerenciador de Contatos permite que você armazene informações de contato – nomes, números de telefone e endereços de email – para uma lista de pessoas.
Criamos o aplicativo em várias iterações. A cada iteração, aprimoramos gradualmente o aplicativo. O objetivo dessa abordagem de iteração múltipla é permitir que você entenda o motivo de cada alteração.
Iteração nº 1 – Criar o aplicativo. Na primeira iteração, criamos o Gerenciador de Contatos da maneira mais simples possível. Adicionamos suporte para operações básicas de banco de dados: CRIAR, Ler, Atualizar e Excluir (CRUD).
Iteração nº 2 – deixe o aplicativo bonito. Nesta iteração, melhoramos a aparência do aplicativo modificando o padrão ASP.NET exibição MVC master página e folha de estilos em cascata.
Iteração nº 3 – Adicionar validação de formulário. Na terceira iteração, adicionamos validação de formulário básico. Impedimos que as pessoas enviem um formulário sem concluir os campos de formulário necessários. Também validamos endereços de email e números de telefone.
Iteração nº 4 – acoplar o aplicativo de forma flexível. Nesta quarta iteração, aproveitamos vários padrões de design de software para facilitar a manutenção e a modificação do aplicativo Contact Manager. Por exemplo, refatoramos nosso aplicativo para usar o padrão de repositório e o padrão de Injeção de Dependência.
Iteração nº 5 – Criar testes de unidade. Na quinta iteração, facilitamos a manutenção e a modificação do aplicativo adicionando testes de unidade. Simulamos nossas classes de modelo de dados e criamos testes de unidade para nossos controladores e lógica de validação.
Iteração nº 6 – Usar o desenvolvimento controlado por teste. Nesta sexta iteração, adicionamos uma nova funcionalidade ao nosso aplicativo escrevendo testes de unidade primeiro e escrevendo código nos testes de unidade. Nesta iteração, adicionamos grupos de contatos.
Iteração nº 7 – Adicionar funcionalidade do Ajax. Na sétima iteração, melhoramos a capacidade de resposta e o desempenho de nosso aplicativo adicionando suporte ao Ajax.
Esta iteração
Nesta iteração do aplicativo Contact Manager, refatoramos nosso aplicativo para fazer uso do Ajax. Aproveitando o Ajax, tornamos nosso aplicativo mais responsivo. Podemos evitar renderizar uma página inteira quando precisamos atualizar apenas uma determinada região em uma página.
Refatoraremos nossa exibição de Índice para que não seja necessário refazer a reprodução da página inteira sempre que alguém selecionar um novo grupo de contatos. Em vez disso, quando alguém clicar em um grupo de contatos, apenas atualizaremos a lista de contatos e deixaremos o restante da página em paz.
Também alteraremos a maneira como nosso link de exclusão funciona. Em vez de exibir uma página de confirmação separada, exibiremos uma caixa de diálogo de confirmação do JavaScript. Se você confirmar que deseja excluir um contato, uma operação HTTP DELETE será executada no servidor para excluir o registro de contato do banco de dados.
Além disso, aproveitaremos o jQuery para adicionar efeitos de animação à nossa exibição índice. Exibiremos uma animação quando a nova lista de contatos estiver sendo buscada do servidor.
Por fim, aproveitaremos o suporte ASP.NET estrutura AJAX para gerenciar o histórico do navegador. Criaremos pontos de histórico sempre que executarmos uma chamada do Ajax para atualizar a lista de contatos. Dessa forma, os botões para trás e para frente do navegador funcionarão.
Por que usar o Ajax?
O uso do Ajax tem muitos benefícios. Primeiro, adicionar a funcionalidade do Ajax a um aplicativo resulta em uma melhor experiência do usuário. Em um aplicativo Web normal, toda a página deve ser postada de volta no servidor sempre que um usuário executa uma ação. Sempre que você executa uma ação, o navegador bloqueia e o usuário deve aguardar até que toda a página seja buscada e reproduzida.
Essa seria uma experiência inaceitável no caso de um aplicativo da área de trabalho. Mas, tradicionalmente, vivemos com essa experiência de usuário ruim no caso de um aplicativo Web porque não sabíamos que poderíamos fazer melhor. Pensamos que era uma limitação dos aplicativos Web quando, na realidade, era apenas uma limitação de nossa imaginação.
Em um aplicativo Ajax, você não precisa interromper a experiência do usuário apenas para atualizar uma página. Em vez disso, você pode executar uma solicitação assíncrona em segundo plano para atualizar a página. Você não força o usuário a aguardar enquanto parte da página é atualizada.
Aproveitando o Ajax, você também pode melhorar o desempenho do aplicativo. Considere como o aplicativo Gerenciador de Contatos funciona agora sem a funcionalidade do Ajax. Quando você clica em um grupo de contatos, toda a exibição índice deve ser reproduzida. A lista de contatos e a lista de grupos de contatos devem ser recuperadas do servidor de banco de dados. Todos esses dados devem ser passados pela transmissão do servidor Web para o navegador da Web.
No entanto, depois de adicionarmos a funcionalidade do Ajax ao nosso aplicativo, podemos evitar a reprodução redisplay da página inteira quando um usuário clica em um grupo de contatos. Não precisamos mais capturar os grupos de contatos do banco de dados. Também não precisamos efetuar push de toda a exibição indexação pela transmissão. Aproveitando o Ajax, reduzimos a quantidade de trabalho que nosso servidor de banco de dados deve executar e reduzimos a quantidade de tráfego de rede exigida por nosso aplicativo.
Não tenha medo do Ajax
Alguns desenvolvedores evitam usar o Ajax porque se preocupam com navegadores de nível inferior. Eles querem ter certeza de que seus aplicativos Web ainda funcionarão quando acessados por um navegador que não dá suporte a JavaScript. Como o Ajax depende do JavaScript, alguns desenvolvedores evitam usar o Ajax.
No entanto, se você tiver cuidado com a implementação do Ajax, poderá criar aplicativos que funcionam com navegadores de nível superior e inferior. Nosso aplicativo Do Contact Manager funcionará com navegadores que dão suporte a JavaScript e navegadores que não o fazem.
Se você usar o aplicativo Contact Manager com um navegador compatível com JavaScript, terá uma melhor experiência do usuário. Por exemplo, quando você clica em um grupo de contatos, somente a região da página que exibe contatos será atualizada.
Se, por outro lado, você usar o aplicativo Contact Manager com um navegador que não dá suporte a JavaScript (ou que tenha JavaScript desabilitado), você terá uma experiência de usuário um pouco menos desejável. Por exemplo, quando você clica em um grupo de contatos, toda a exibição índice deve ser postada de volta no navegador para exibir a lista correspondente de contatos.
Adicionando os arquivos JavaScript necessários
Precisaremos usar três arquivos JavaScript para adicionar a funcionalidade do Ajax ao nosso aplicativo. Todos esses três arquivos estão incluídos na pasta Scripts de um novo aplicativo ASP.NET MVC.
Se você planeja usar o Ajax em várias páginas em seu aplicativo, faz sentido incluir os arquivos JavaScript necessários no modo de exibição do aplicativo master página. Dessa forma, os arquivos JavaScript serão incluídos em todas as páginas do aplicativo automaticamente.
Adicione as seguintes inclusões JavaScript dentro da <marca de cabeçalho> do modo de exibição master página:
<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>
Refatorando a exibição de índice para usar o Ajax
Vamos começar modificando nossa exibição índice para que clicar em um grupo de contatos atualize apenas a região da exibição que exibe contatos. A caixa vermelha na Figura 1 contém a região que queremos atualizar.
Figura 01: atualizando apenas contatos (Clique para exibir imagem em tamanho real)
A primeira etapa é separar a parte da exibição que desejamos atualizar de forma assíncrona em uma parcial separada (exibir controle do usuário). A seção da exibição Índice que exibe a tabela de contatos foi movida para a parcial na Listagem 1.
Listagem 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>
Observe que a parcial na Listagem 1 tem um modelo diferente do modo de exibição Índice. O atributo Inherits na <diretiva %@ Page %> especifica que a parcial herda da classe ViewUserControl<Group> .
A exibição índice atualizada está contida na Listagem 2.
Listagem 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>
Há duas coisas que você deve observar sobre a exibição atualizada na Listagem 2. Primeiro, observe que todo o conteúdo movido para a parcial é substituído por uma chamada para Html.RenderPartial(). O método Html.RenderPartial() é chamado quando a exibição Index é solicitada pela primeira vez para exibir o conjunto inicial de contatos.
Em segundo lugar, observe que o Html.ActionLink() usado para exibir grupos de contatos foi substituído por um Ajax.ActionLink(). O Ajax.ActionLink() é chamado com os seguintes parâmetros:
<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList"})%>
O primeiro parâmetro representa o texto a ser exibido para o link, o segundo parâmetro representa os valores de rota e o terceiro parâmetro representa as opções do Ajax. Nesse caso, usamos a opção UpdateTargetId Ajax para apontar para a <marca html div> que queremos atualizar após a conclusão da solicitação do Ajax. Queremos atualizar a <marca div> com a nova lista de contatos.
O método Index() atualizado do controlador contact está contido na Listagem 3.
Listagem 3 – Controllers\ContactController.cs (método Index)
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);
}
A ação index() atualizada retorna condicionalmente uma das duas coisas. Se a ação Index() for invocada por uma solicitação Ajax, o controlador retornará uma parcial. Caso contrário, a ação Index() retornará uma exibição inteira.
Observe que a ação Index() não precisa retornar tantos dados quando invocada por uma solicitação do Ajax. No contexto de uma solicitação normal, a ação Índice retorna uma lista de todos os grupos de contatos e o grupo de contatos selecionado. No contexto de uma solicitação Ajax, a ação Index() retorna apenas o grupo selecionado. Ajax significa menos trabalho no servidor de banco de dados.
Nossa exibição de Índice modificada funciona no caso de navegadores de nível superior e inferior. Se você clicar em um grupo de contatos e o navegador der suporte ao JavaScript, somente a região do modo de exibição que contém a lista de contatos será atualizada. Se, por outro lado, o navegador não oferecer suporte a JavaScript, o modo de exibição inteiro será atualizado.
Nossa exibição de Índice atualizada tem um problema. Quando você clica em um grupo de contatos, o grupo selecionado não é realçado. Como a lista de grupos é exibida fora da região que é atualizada durante uma solicitação do Ajax, o grupo certo não é realçado. Corrigiremos esse problema na próxima seção.
Adicionando efeitos de animação jQuery
Normalmente, quando você clica em um link em uma página da Web, pode usar a barra de progresso do navegador para detectar se o navegador está buscando ou não o conteúdo atualizado ativamente. Ao executar uma solicitação do Ajax, por outro lado, a barra de progresso do navegador não mostra nenhum progresso. Isso pode deixar os usuários nervosos. Como você sabe se o navegador foi congelado?
Há várias maneiras de indicar a um usuário que o trabalho está sendo executado durante a execução de uma solicitação do Ajax. Uma abordagem é exibir uma animação simples. Por exemplo, você pode esmaecer uma região quando uma solicitação do Ajax começar e desaparecer na região quando a solicitação for concluída.
Usaremos a biblioteca jQuery incluída na estrutura do Microsoft ASP.NET MVC para criar os efeitos de animação. A exibição índice atualizada está contida na Listagem 4.
Listagem 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>
Observe que a exibição de Índice atualizada contém três novas funções JavaScript. As duas primeiras funções usam jQuery para esmaecer e desaparecer na lista de contatos quando você clica em um novo grupo de contatos. A terceira função exibe uma mensagem de erro quando uma solicitação do Ajax resulta em um erro (por exemplo, tempo limite de rede).
A primeira função também cuida de realçar o grupo selecionado. Um atributo class= selecionado é adicionado ao elemento pai (o elemento LI) do elemento clicado. Novamente, o jQuery facilita a seleção do elemento certo e a adição da classe CSS.
Esses scripts estão vinculados aos links de grupo com a ajuda do parâmetro Ajax.ActionLink() AjaxOptions. A chamada de método Ajax.ActionLink() atualizada é semelhante a esta:
<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>
Adicionando suporte ao histórico do navegador
Normalmente, quando você clica em um link para atualizar uma página, o histórico do navegador é atualizado. Dessa forma, você pode clicar no botão Voltar do navegador para voltar no tempo para o estado anterior da página. Por exemplo, se você clicar no grupo de contatos Amigos e clicar no grupo Contato comercial, poderá clicar no botão Voltar do navegador para navegar de volta para o estado da página quando o grupo de contatos Amigos foi selecionado.
Infelizmente, executar uma solicitação do Ajax não atualiza o histórico do navegador automaticamente. Se você clicar em um grupo de contatos e a lista de contatos correspondentes for recuperada com uma solicitação do Ajax, o histórico do navegador não será atualizado. Você não pode usar o botão Voltar do navegador para navegar de volta para um grupo de contatos depois de selecionar um novo grupo de contatos.
Se você quiser que os usuários possam usar o botão Voltar do navegador depois de executar solicitações do Ajax, será necessário executar um pouco mais de trabalho. Você precisa aproveitar a funcionalidade de gerenciamento de histórico do navegador criada no ASP.NET AJAX Framework.
ASP.NET histórico do navegador AJAX, você precisa fazer três coisas:
- Habilite o Histórico do Navegador definindo a propriedade enableBrowserHistory como true.
- Salve pontos de histórico quando o estado de uma exibição for alterado chamando o método addHistoryPoint().
- Reconstrua o estado da exibição quando o evento de navegação é gerado.
A exibição índice atualizada está contida na Listagem 5.
Listagem 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>
Na Listagem 5, o Histórico do Navegador está habilitado na função pageInit(). A função pageInit() também é usada para configurar o manipulador de eventos para o evento de navegação. O evento de navegação é gerado sempre que o botão Avançar ou Voltar do navegador faz com que o estado da página seja alterado.
O método beginContactList() é chamado quando você clica em um grupo de contatos. Esse método cria um novo ponto de histórico chamando o método addHistoryPoint(). A ID do grupo de contatos clicado é adicionada ao histórico.
A ID do grupo é recuperada de um atributo expando no link do grupo de contatos. O link é renderizado com a chamada a seguir para 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})%>
O último parâmetro passado para a Ajax.ActionLink() adiciona um atributo expando chamado groupid ao link (minúscula para compatibilidade XHTML).
Quando um usuário atinge o botão Voltar ou Encaminhar do navegador, o evento de navegação é acionado e o método navigate() é chamado. Esse método atualiza os contatos exibidos na página para corresponder ao estado da página que corresponde ao ponto de histórico do navegador passado para o método de navegação.
Executando exclusões do Ajax
Atualmente, para excluir um contato, você precisa clicar no link Excluir e, em seguida, clicar no botão Excluir exibido na página de confirmação de exclusão (consulte a Figura 2). Isso parece um monte de solicitações de página para fazer algo simples como excluir um registro de banco de dados.
Figura 02: a página de confirmação de exclusão (Clique para exibir a imagem em tamanho real)
É tentador ignorar a página de confirmação de exclusão e excluir um contato diretamente da exibição Índice. Você deve evitar essa tentação porque tomar essa abordagem abre seu aplicativo para falhas de segurança. Em geral, você não deseja executar uma operação HTTP GET ao invocar uma ação que modifica o estado do aplicativo Web. Ao executar uma exclusão, você deseja executar um HTTP POST, ou melhor ainda, uma operação HTTP DELETE.
O link Excluir está contido na parcial ContactList. Uma versão atualizada da parcial ContactList está contida na Listagem 6.
Listagem 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>
O link Excluir é renderizado com a seguinte chamada para o método Ajax.ImageActionLink():
<%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" })%>
Observação
O Ajax.ImageActionLink() não é uma parte padrão da estrutura ASP.NET MVC. O Ajax.ImageActionLink() é um método auxiliar personalizado incluído no projeto do Contact Manager.
O parâmetro AjaxOptions tem duas propriedades. Primeiro, a propriedade Confirm é usada para exibir uma caixa de diálogo de confirmação do JavaScript pop-up. Em segundo lugar, a propriedade HttpMethod é usada para executar uma operação HTTP DELETE.
A listagem 7 contém uma nova ação AjaxDelete() que foi adicionada ao controlador de contato.
Listagem 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);
}
A ação AjaxDelete() é decorada com um atributo AcceptVerbs. Esse atributo impede que a ação seja invocada, exceto por qualquer operação HTTP que não seja uma operação HTTP DELETE. Em particular, você não pode invocar essa ação com um HTTP GET.
Depois de excluir o registro do banco de dados, você precisa exibir a lista atualizada de contatos que não contém o registro excluído. O método AjaxDelete() retorna a parcial ContactList e a lista atualizada de contatos.
Resumo
Nesta iteração, adicionamos a funcionalidade do Ajax ao aplicativo Contact Manager. Usamos o Ajax para melhorar a capacidade de resposta e o desempenho do nosso aplicativo.
Primeiro, refatoramos a exibição Índice para que clicar em um grupo de contatos não atualize a exibição inteira. Em vez disso, clicar em um grupo de contatos atualiza apenas a lista de contatos.
Em seguida, usamos efeitos de animação jQuery para esmaecer e desaparecer na lista de contatos. A adição de animação a um aplicativo Ajax pode ser usada para fornecer aos usuários do aplicativo o equivalente a uma barra de progresso do navegador.
Também adicionamos suporte ao histórico do navegador ao nosso aplicativo Ajax. Permitimos que os usuários clicassem nos botões Voltar e Encaminhar do navegador para alterar o estado da exibição Índice.
Por fim, criamos um link de exclusão que dá suporte a operações HTTP DELETE. Ao executar exclusões do Ajax, permitimos que os usuários excluam registros de banco de dados sem exigir que o usuário solicite uma página de confirmação de exclusão adicional.