Este artigo foi traduzido por máquina.

Cutting Edge

Vá além do formulários HTML com AJAX

Dino Esposito

Download do código disponível na Galeria de código do MSDN
Procure o código on-line

Conteúdo

Formulários pop-up
Validação Just-in-Time
Otimização de envio
Auto-salvar formulários
AJAX E posteriores

Além do hype da experiência do usuário aprimorada, mais interatividade, cintilação de página menor, transferência de dados mais rápida e todos os as outras melhorias promessas de AJAX, a alteração da chave que AJAX para a tabela é que ele permite você total controle sobre o envio de dados para o servidor.

Em um aplicativo AJAX puro, qualquer envio de dados do navegador-para-servidor passa através do código do desenvolvedor. Como desenvolvedor, você decidir como enviar dados e quando. Além disso, você ainda pode decidir se ou não um formulário deve ser usado.

Para obter esse um nível de controle sobre o processo de envio de dados em um aplicativo baseado em navegador, você está necessário escrever muito código JavaScript. Na verdade, em prestações anteriores desta coluna, discuti os principais recursos de uma biblioteca JavaScript bastante popular — a biblioteca jQuery — que pode oferecer uma grande quantidade de ajuda ao escrever código JavaScript sério.

Este mês, irá examinar alguns cenários que envolvam formas no contexto de aplicativos AJAX. Irá examinar diversas abordagens para implementação de recursos, como a validação de salvamento automático, just-in-time e a otimização de envio. Vamos começar com formulários pop-up.

Formulários pop-up

No mês passado, apresentadas um subconjunto da biblioteca, o jQuery biblioteca de interface do usuário, que foi desenvolvido especificamente para simplificar a criação de interfaces de usuário sofisticada através de janelas restritas e sem janela restrita e avançadas e eficiente widgets como accordions e tabulações do jQuery.

Em um contexto da Web, no entanto, um formulário pop-up pode não ser a melhor solução para exibir dados que resulta de operações de busca detalhada. A janela pop-up normalmente é criada usando o navegador API — normalmente, o método window.open — e está sujeita à diretiva de Bloqueador de pop-up que o usuário tem no local para esse site. O trecho de código a seguir mostra como forçar o navegador para exibir uma janela pop-up:

window.open(url, 'Sample', 'width=400,height=300,scrollbars=yes'); 

Pop-up será exibida a página especificada na URL e pode postar dados em qualquer outra página no aplicativo. Você pode passar dados para o pop-up usando a seqüência de consulta; como alternativa, você pode recuperar campos de entrada do formulário pai através da propriedade opener do objeto janela. Você chamar o objeto de janela de dentro a página exibida em pop-up, desta forma:

var text = window.opener.document.Form1["TextBox1"].value;

Da propriedade opener você acessar o modelo de objeto do formulário opener e ler o conteúdo de um formulário específico por meio de HTML DOM.

O abuso de pop-up e pop-under formulários na Web anunciando os desenvolvedores navegador led apresentar recursos para controlar a proliferação de janelas desse tipo. Como resultado, mesmo legítimo uso de pop-ups para transmitir informações para o usuário é perder apelo e tornando-se quase impossível.

Hoje, os formulários de pop-up em aplicativos da Web são principalmente superior DIV conteúdo exibido de uma maneira restrita, depois de desativar a capacidade de clicar no elementos abaixo. A interface do usuário do pop-up não necessariamente pertence a uma página separada; mais freqüentemente que não, ela é apenas parte da página que exibe a ele. Ele pode ser uma marca DIV inicialmente oculta que fica visível quando o código de script apropriado é executado.

Em tal uma janela de pop-up de pseudo, você pode facilmente acessar qualquer elemento na página porque o conteúdo da janela popup da pseudo já faz parte de página. Inicializar os elementos input, portanto, não é mais um problema.

Bibliotecas poderosas, como o jQuery da interface do usuário também oferecem recursos para controlar a aparência dessas pop-ups para torná-los aparência clássicas caixas de diálogo do Windows. (Consulte a Figura 1 ).

A marcação que você colocar em pop-up pode ou não incluir uma marca de formulário. Com certeza, ele não pode incluir qualquer elemento de formulário adicionais do lado do servidor desde que a página host seja uma página ASP.NET. Um elemento de formulário HTML (do runat = atributo do servidor) pode ser inserido se a página é clássico ASP.NET ou ASP.NET MVC. Se o pop-up contiver uma marca de formulário, em seguida, você pode tirar proveito dos recursos de envio do navegador para enviar dados para a URL de ação da opção. Caso contrário, lançamento ainda é possível, mas você deve escrever o código.

fig01.gif

Figura 1 um exemplo caixa de diálogo caixa criados com jQuery 1.7 de interface do usuário

Você pode percorrer os campos de entrada, preparar o corpo de uma solicitação HTTP e lançá-lo usando o objeto XMLHttpRequest diretamente ou qualquer abstração do, como (a $ .AJAX função em jQuery.) ou o objeto Sys.Net.WebRequest na biblioteca cliente Microsoft AJAX

Finalmente, para manter o conteúdo do pop-up fisicamente separado do restante da página ASP.NET, convém defini-la em um controle de usuário ASCX, assim:

<div id="DialogBox1">
  <cc1:YourUserControl runat="server"     ID="DialogBox1_Content" />
</div>

Essa abordagem pode ser retirada em ambos os ASP.NET clássica e em páginas ASP.NET MVC.

Validação Just-in-Time

É bastante comum que um formulário da Web é necessário para notificar o usuário sobre os valores incorretos antes do envio. Notificar o usuário de entrada incorreta é um trabalho que controles de validação do ASP.NET faz muito bem. O ValidatorCalloutExtender no AJAX Control Toolkit, em seguida, também pode tornar avisos de entrada inválidos atraentes, como você ver na Figura 2 .

fig02.gif

A Figura 2 validador Extensores em uma interface do usuário

Controles de validação ASP.NET trabalho por validar o conteúdo inteiro do formulário quando ele for enviado. Na versão atual do ASP.NET, não há nenhum assíncrono validador personalizado que permite o código de cliente validar campos em uma regra de servidor (personalizados). Tal um componente, no entanto, pode ser liberado em versões futuras do ASP.NET.

Em resumo, para detectar e relatar valores incorretos para o usuário é necessário duas abordagens possíveis. Primeiro, você pode associar um validator assíncrono com qualquer campo de entrada e mensagens de erro do relatório como o valor do campo é alterado. Em segundo lugar, você pode validar o conteúdo do formulário como um todo. Essa segunda abordagem pode ser implementada de duas maneiras: você pode simplesmente enviar o formulário da maneira normal por meio do navegador e aguardar a resposta do servidor, ou você pode de maneira assíncrona e programaticamente enviar o conteúdo do formulário, até mesmo conteúdo parcial, com comentários de início. Vamos examinar as várias abordagens e ver como tirar proveito dos recursos do AJAX.

No ASP.NET, há um número de controles de validação predefinidas que aplicar regras de fixos para o conteúdo do campo e determinar se a entrada é válida ou não (em inglês). Exemplo validadores executar verificações, como se um campo for deixado vazio, uma data cair dentro de um determinado intervalo ou parte do conteúdo é igual a um determinado valor ou corresponde a uma determinada expressão regular. Essas verificações abrangem necessidades comuns de validação. No entanto, a verificação mais comum deve ser executada no servidor e requer uma conexão de banco de dados, um fluxo de trabalho ou talvez um serviço da Web. Para esses casos, o ASP.NET fornece o controle CustomValidator.

CustomValidator é um excelente controle que permite que você especificar uma função de JavaScript do cliente e um método de servidor para verificar os comentários de valor e o relatório para o nível da interface do usuário. Corretamente empacotada no backup uma atualização do AJAX-painel, o controle CustomValidator também pode retornar sua resposta assincronamente, evitando uma atualização de página inteira. A única desvantagem do CustomValidator é que, assim como qualquer outro validador, ele não verificar o valor até que o formulário é submetido. Vamos considerar o código na Figura 3 .

Figura 3 uma implementação do painel de atualização

<asp:UpdatePanel runat="server" ID="UpdatePanel1">
  <ContentTemplate>
    <asp:TextBox ID="TextBox1" runat="server" 
                 AutoPostBack="true" />
    <asp:CustomValidator ID="CustomValidator1" runat="server" 
                 Display="Dynamic" 
                 ControlToValidate="TextBox1" 
                 SetFocusOnError="true" 
                 ErrorMessage="Invalid ID"
                 OnServerValidate=" CustomValidator1_Validate" >
   </asp:CustomValidator> 
 </ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="Button1" runat="server" Text="Submit" />

A página envia de volta como o usuário edita o conteúdo da caixa de texto. Uma instância de CustomValidator está associada com a caixa de texto e sabe como validar o conteúdo. A atualização-painel garante que um postback gerará apenas uma atualização parcial. Infelizmente, esse código não produzem os resultados esperados. A página envia de volta como a caixa de texto é editada, mas nenhuma validação ocorre nunca. Para disparar o validador personalizado, o usuário precisa pressione o botão Enviar.

O problema é que nenhum caminho de código leva à invocação do método Validate na classe de página fora o processo de envio do formulário clássico. Para corrigir isso, você deve verificar se um postback assíncrono está acontecendo e chamar Validate você mesmo, como mostrado abaixo:

protected void Page_Load(object sender,     EventArgs e)
{
    if (ScriptManager1.IsInAsyncPostBack)
    {
        this.Validate();
    }
}

O método Validate, por sua vez, irá loop os validadores na página e relatório sobre os valores incorretos na página.

Se seu objetivo é relatar erros de entrada assim que possível, a única alternativa para a abordagem anterior é adicionar um código JavaScript aos campos de entrada críticos. Aqui está um exemplo:

 <asp:TextBox ID="TextBox1" runat="server" 
              onchange="__doValidation(this)" />

Em uma caixa de texto, o evento onchange não é acionado quando o usuário está digitação, mas somente quando o usuário pressiona fora da caixa de texto e implicitamente confirma as alterações. No trecho de código anterior, um manipulador de JavaScript é executado para executar uma validação remota via XMLHttpRequest. Eis o código para o manipulador de JavaScript:

<script type="text/javascript">
    function __doValidation(textBox) {
        var text = textBox.value;
        PageMethods.PerformValidation(text, onComplete);
    }

    function onComplete(results) {
        if (results == false)
            $get("Label1").innerHTML = "Invalid ID";
        else
            $get("Label1").innerHTML = "";
    } </script>

Como você pode ver, o exemplo usa um método de página ASP.NET para definir o ponto de extremidade HTTP para ser chamado. Esse ponto de extremidade qualquer é muito bem, incluindo um método de serviço WCF, um método de serviço da Web ou um serviço REST. A resposta que você obter o ponto de extremidade HTTP pode ser um valor booleano ou um pedaço de marcação HTML. No caso anterior, a lógica que atualiza a interface do usuário reside no cliente (e talvez seja realmente simple); no último caso, mais sofisticada lógica é necessários no servidor.

Se você não precisa validar entrada campos individualmente e pode Aguarde comentários até que todo o formulário seja enviado, a coisa mais simples que pode fazer é usar validadores em um controle UpdatePanel do ASP.NET. Nesse caso, tenha em mente que validators e controles de entrada devem ser colocados no mesmo painel.

Como alternativa ao parcial processamento para lançamento e validar o conteúdo de um formulário, você pode considerar uma biblioteca AJAX, como jQuery em combinação com o plug-in Form e validação. Um exemplo é discutido no artigo" Combinando JQuery formulário validação e envio de AJAX com ASP.NET."

Em geral, eu acredito que verificações individuais são preferível porque você capturar valores incorretos imediatamente e você pode ajustar o formulário dinamicamente para refletir a entrada atual. Por enquanto, você precisará usar o JavaScript ou talvez fazer o processamento parcial com controles de postback automático.

Se você pretende validar todo o formulário de forma assíncrona, eu ainda acredito que usar clássicos validadores do ASP.NET com o processamento parcial é a opção mais simples. Igualmente eficaz é qualquer solução que serializa o conteúdo do formulário em uma seqüência de caracteres e envia que para um ponto de extremidade HTTP usando a biblioteca AJAX de escolha. Como você verá em instantes, serialização personalizada e lançamento de um formulário fornece para os recursos mais avançados.

Otimização de envio

Com o AJAX, você não tenha apenas uma maneira de enviar o conteúdo de um formulário para o servidor Web. Você pode certamente fazer isso explicitamente por meio de um botão de envio ou através de programação pelo método envio do objeto HTML DOM formulário. Mais importante, porém, você pode considerar enviar conteúdo para o servidor em blocos e em várias etapas em vez de todas ao mesmo tempo. Pattern-Wise, se você optar por enviar todo o conteúdo de um formulário ao mesmo tempo, em seguida, você está aplicando o padrão de "envio Explicit"; caso contrário, você é otimização seu envio via o padrão de "envio otimização" (estado).

O padrão de curto PRAZO comprova útil para suavização o impacto de operações de cliente que colocam pressão no servidor, incluindo operações que resultam em freqüentes viagens de ida e volta. Isso torna o estado padrão a estratégia de chave para implementação de recursos bom, como formulários de salvamento automático.

Simplificando, o padrão de curto PRAZO sugere cache o conteúdo para enviar em um buffer do navegador e enviá-lo gradativamente, em várias etapas. O exemplo canônico é o mecanismo de preenchimento automático. Como os tipos de usuário em uma caixa de texto, uma solicitação é feita para o servidor para sugestões. É fácil descobrir que o número de solicitações que o servidor Web de visitas em horários de pico é muito alto.

Para acessar um compromisso razoável entre a capacidade de resposta do aplicativo e carga de trabalho de servidor da Web, convém assumir o controle sobre o processo de envio. Para entender a otimização, vamos examinar o código-fonte do extensor do recurso Preenchimento Automático da Microsoft, que você irá localizar no AJAX Control Toolkit.

O extensor do preenchimento automático envia uma solicitação de sugestões enquanto o usuário digita na caixa de entrada. Com base nisso, uma espera um manipulador para o evento keypress que chama o serviço da Web especificado. No entanto, uma visão mais detalhada o código-fonte revela que ele funciona de forma diferente, conforme ilustra a Figura 4 .

Figura 4 postbacks controlado por um timer

// Handler for the textbox keydown event
onKeyDown: function(ev) 
{
    // A key has been pressed, so let's reset the timer
    this._timer.set_enabled(false);

    // Is it a special key?
    if (k === Sys.UI.Key.esc) {
       ...
    }
    else if (k === Sys.UI.Key.up) {
       ...
    }
       ...
    else {
       // It's a text key, let's start the timer again 
       this._timer.set_enabled(true);
    }     
}

O extensor usa um timer interno configurado para um intervalo de um segundo (por padrão). O timer é iniciado quando a caixa de texto obtém o foco de entrada. Assim que uma tecla é pressionada para baixo, o timer é interrompido e uma análise da chave começa. Se a chave for um com um significado especial, como ENTER, ESC, guia ou uma tecla de direção, em seguida, o extensor prosseguirá com seu próprio código. Se a tecla pressionada indicar conteúdo a ser inserido no buffer de caixa de texto, em seguida, o timer é iniciado.

O timer é interrompido e reiniciado sempre que uma chave real é digitada. Se você interromper a digitação de um segundo (ou qualquer intervalo que você configurar), em seguida, em escala do timer, o conteúdo real do campo de entrada é enviado para receber sugestões. Não é uma grande alteração para os usuários, mas é boa notícia para o servidor porque nenhum postback ocorre até que o usuário digita. Se o usuário usa uma quebra de um segundo, o timer expira e o postback, em seguida, será feito.

Timers são uma ferramenta poderosa em JavaScript porque seu comportamento assíncrono inerente pode ser aproveitado para simular multithreading. Criando um cronômetro em JavaScript, você está solicitando o interpretador para executar o código associado assim que possível, mas não imediatamente. Se o código for bastante simples e o intervalo de timer apropriado, em seguida, o interpretador poderão agendar a execução corretamente, assim avançando várias tarefas ao mesmo tempo.

Auto-salvar formulários

Não é incomum em aplicativos AJAX que o usuário gasta muito tempo de trabalho em um único formulário, mas sem enviar os dados para o servidor Web por um tempo. O servidor Web não tem como descobrir o que está acontecendo no cliente. Posteriormente, se ele não receber solicitações por um período de tempo, ela deve ter apenas o tempo limite de sessão de servidor. Portanto, quando o usuário Finalmente envia o formulário completo para o servidor, ela será exibida uma surpresa desagradável (uma mensagem de tempo limite).

Para evitar que, o aplicativo de cliente envia uma mensagem de "pulsação" via XMLHttpRequest com uma freqüência apropriada. Uma mensagem de pulsação pode levar a qualquer formulário e conteúdo que é adequado para o cenário em particular. Por exemplo, pode ser uma solicitação vazia que apenas mostra que o cliente ainda está funcionando e foi o único objetivo de manter a sessão do servidor atualizado e execução. (Nesse caso, o intervalo deve ser de qualquer tamanho que é menor que o tempo limite da sessão configurado para o aplicativo.)

A pulsação ainda pode conter o conteúdo atual, possivelmente parcial, do formulário. Tal conteúdo é carregados periodicamente e armazenado em cache no servidor aguardando o tempo apropriado para processá-la. A idéia geral não é muito diferente do que o recurso de salvamento automático do Microsoft Office Word, onde o documento aberto periodicamente salva novamente em disco para evitar a perda de dados.

Pela Web, formulários de salvamento automático tem um comportamento muito menos definido e sua implementação interna amplamente é deixada para as necessidades do desenvolvedor e criatividade. Formulários de salvamento automático são, essencialmente, os formulários endowed a capacidade de enviar periodicamente seus conteúdos para um URL. A URL de recebimento será, em seguida, manipular dados e cache normalmente para o usuário atual. a Figura 5 mostra um exemplo.

A Figura 5 implementação de um formulário de auto-salvar

<script type="text/javascript">
    var _myTimerID = null;
    var _userID = null;
    function enableAutoSave(id) {
        _userID = id;
        _myTimerID = window.setInterval(__doAutoSave, 10000);
    }

    function __doAutoSave() {
        var body = "ID='" + _userID + "'&" +
                   "TextBox2='" + $get("TextBox2").value + "'&" +
                   "TextBox3='" + $get("TextBox3").value + "'&" +
                   "TextBox4='" + $get("TextBox4").value + "'";

        PageMethods.AutoSave(_userID, body, onComplete);
    }

    function onComplete(results) {
        $get("Msg").innerHTML = "<i>Form auto-saved for user '" + 
              _userID + "' at " + results + ".</i>";
    }
</script>

<body>
    ...
</body>

// In the code-behind class ...
protected void Button1_Click(object sender, EventArgs e)
{
    string user = TextBox1.Text;

    // Populate input fields if any previously entered 
    // data is available
    string body = AutoSaveAPI.Read(user);
    if (!String.IsNullOrEmpty(body))
    {
        Dictionary<string, object> data = body.ParseToDictionary();
        TextBox2.Text = data["TextBox2"] as string;
        TextBox3.Text = data["TextBox3"] as string;
        TextBox4.Text = data["TextBox4"] as string;
    }

    // Re-enable auto-save for this editing session
    string script = "enableAutoSave('" + user + "');";
    ScriptManager.RegisterStartupScript(this, this.GetType(), 
                  "myTimer", script, true);
}

[WebMethod]
public static string AutoSave(string id, string body)
{
    AutoSaveAPI.Save(id, body);
    return DateTime.Now.ToString();
}

Depois que o usuário navega para o formulário, a classe codebehind carrega os dados inseridos anteriormente para esse formulário. Normalmente, os dados é lido da cache ou de qualquer outra fonte de escolha. Na Figura 5 , o armazenamento está oculto por trás da interface da classe AutoSaveAPI. Qualquer informação ler é usada para preencher os campos de entrada no formulário.

Para ativar automaticamente-salvar em uma nova sessão de entrada de dados, emitir uma linha do script que aciona um timer. Quando o timer de tiques, o retorno de chamada coleta os valores atuais nos campos de várias e cria uma seqüência de caracteres. A seqüência de caracteres é carregada, em seguida, usar XMLHttpRequest. Você pode carregá-lo para um serviço da Web, uma URL simples usando uma abordagem REST, ou até mesmo para um método de página. Como um formulário de salvamento automático é um componente específico de uma determinada página, usando um método de página é a solução ideal, porque é limitado de página, eficiente e fácil ao código. a Figura 6 mostra um formulário de salvamento automático em ação.

fig06.gif

A Figura 6 um formulário de auto-salvar em ação

AJAX E posteriores

Com o AJAX, a marca de formulário HTML antiga precisa alguns revisão. Com o padrão HTML 5.0 futuro, um novo conjunto de entradas, incluindo URL, a data e o email será manipulado nativamente pelos navegadores. Isso reduzirá o número de ocorrências para o qual scripts e validadores são necessários. Esta evolução do HTML permitirá que você se concentrar na validação do servidor, que deve ser assíncrona em aplicativos do AJAX.

Envie suas dúvidas e comentários para Dino para cutting@microsoft.com.

Dino Esposito é um arquiteto na arquitetura na IDesign e o co-autor de Microsoft .NET: Architecting Applications for the Enterprise (Microsoft Press, 2008). Residente na Itália, Dino é palestrante assíduo em eventos do setor no mundo inteiro. Você pode ingressar em seu blog em weblogs.asp. NET/despos.