Este artigo foi traduzido por máquina.

Pontos de dados

Fatie e divida OData com o plug-in DataTables do jQuery

Julie Lerman

Baixe o código de exemplo

O protocolo de dados aberto (OData) permite que os produtores de dados fornecer seus dados pela Web em um formato comum que pode ser consumida por qualquer pessoa usando uma tecnologia habilitado o HTTP. Dados são fornecidos por meio de URIs e você pode usar os verbos HTTP comuns — obter, colocar, postar, mesclar e excluir — para interagir com os dados. Você pode manipular essa interação diretamente por meio de uma linguagem como JavaScript ou usando um cliente API, como o Microsoft.NET Framework, Silverlight, PHP ou outras pessoas fornecidos pela Microsoft. De qualquer forma, você pode interagir com todos os feeds de OData da mesma maneira.

Há um número crescente de serviços de OData publicamente fornecidos como feeds comerciais Inc. Netflix e eBay Inc., dados da Copa do mundo, até mesmo um serviço que fornece 150 anos de estatísticas de beisebol.

Acesso a dados está ficando mais fácil e mais fácil, mas por que apresentar os dados? Quando você tem 150 anos de estatísticas de beisebol ou milhares de títulos de filme, ainda há algum esforço no lado do cliente para recuperar e navegar pelos dados.

Em uma recente Vermont.Apresentação do NET User Group no jQuery, eu estava inspirada por um plug-in jQuery chamado DataTables como uma forma de investimento de baixo para permitir que os usuários de fatia e nos dados de grandes quantidades de dados. A potência de DataTables está no seu processamento de blazingly rápida de cliente, embora ele permita a ser mais interativa com o código do lado do servidor, se você desejar.

JQuery é uma tecnologia de Web do lado do cliente (e pode ser usado em qualquer tipo de aplicativo da Web) que simplifica o trabalho com JavaScript. Se você já conversamos com qualquer pessoa que está entrou na onda a jQuery, você encontrará muita paixão por tecnologia. DataTables é um de um número enorme de jQuery plug-ins. E você pode usar o jQuery em qualquer tipo de aplicativo da Web.

Como posso acontecer a maior parte de meu trabalho com o.NET Framework, nesta coluna, que demonstrarei usando alguns dos recursos básicos de plug-in de DataTables em aplicativos usando o ASP.NET MVC e WebForms. No entanto, a lógica no aplicativo de formulários da Web será conduzida pelo código do lado do cliente. Eu estará trabalhando com o serviço de OData de Netflix ( http://odata.netflix.com/v1/Catalog ), que me dá uma oportunidade para mostrar a você como lidar com algumas armadilhas comuns que você pode encontrar ao usar vários serviços de OData.

Você pode baixar o plug-in de DataTables de datatables. NET. Se você é iniciante em consumindo OData, convém deleite visitando a seção de serviços de dados do WCF do MSDN Developer Center em msdn.microsoft.com/data/odata .

OData de consulta com o LINQ e o APIs do cliente

Começaremos com um aplicativo simples do MVC onde eu acrescentei uma referência de serviço para http://odata. netflix.com/V1/Catalog usando o Assistente do Visual Studio Add Service Reference. Isso, por sua vez, cria classes de proxy para me consumir no meu aplicativo e cria um modelo de dados de entidade com base no serviço, conforme mostrado na a Figura 1 . O assistente também adiciona as referências para o.NET Framework OData biblioteca de cliente APIs. Tanto o.NET Framework e o Silverlight OData bibliotecas de cliente tornam o trabalho com agradece bastante simples de OData para o suporte a consultas LINQ.

Figura 1 O projeto MVC no Solution Explorer

Meu controlador de inicialização, HomeController.cs, usa a biblioteca de cliente de OData e o proxy de serviço de consulta para todos os títulos de filme em um determinado gênero: independentes. Os resultados da consulta são retornados para o modo de exibição associado à ação controlador específico:

public ActionResult Index() {
  var svcUri = new Uri("http://odata.
netflix.com//v1//Catalog");

  var context = new NetflixOData.NetflixCatalog(svcUri);
  var query = from genre in context.Genres
              where genre.Name == "Independent"
              from title in genre.Titles
              where title.ReleaseYear>=2007
              select title ;
  var titles = query.ToList();             
  return View(titles);
}

A marcação na exibição de índice de HomeController (\Views\HomeController\index.aspx) é onde toda a lógica de apresentação interessante está sendo executada. Para aproveitar o jQuery e o plug-in de DataTables, você precisará adicionar um conjunto de arquivos de script para seu projeto. Como alternativa, você pode apontar para o conjunto on-line de scripts (consulte o Microsoft AJAX Content Delivery Network em asp.net/ajaxLibrary/CDN.ashx ), mas escolhi hospedá-los localmente. O download para o plug-in de DataTables contém uma pasta \media. (que contém os scripts) que você pode soltar em seu projeto. Você pode ver que já fiz isso a Figura 1 .

Figura 2 contém a listagem de código do arquivo Index.aspx.

Figura 2 A Index.aspx de HomeController

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
 Inherits="System.Web.Mvc.ViewPage<IEnumerable<Title>>" %>
<%@ Import Namespace="JQueryMVC.Controllers" %>
<%@ Import Namespace="JQueryMVC.NetflixOData" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" 
  runat="server">
    Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" 
  runat="server">
  <head>
    <link href="../../media/css/demo-table.css" 
      rel="stylesheet" type="text/css" />
    <script src="../../media/js/jquery.js" 
      type="text/javascript"></script>
    <script src="../../media/js/jquery.dataTables.js" 
      type="text/javascript"></script>

    <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
           $('#Netflix').dataTable();
        });
    </script>
  </head>
  <div>
    <table id="Netflix">
      <thead><tr><th>Title</th>
                 <th>Rating</th>
                 <th>Runtime</th></tr></thead>
      <tbody>
        <% foreach (Title title in Model)
           { %>
             <tr><td><%= title.Name %> </td>
                 <td><%= title.AverageRating %></td>
                 <td><%= title.Runtime %></td></tr>
           <% } %>
      </tbody>
    </table>
  </div>
</asp:Content>

O link CSS e o script de duas fontes no início do <head>ponto de seção para formatação CSS e críticos arquivos JavaScript jQuery e jQuery.datatables.

Em seguida, vamos nos concentrar na tabela como ele é apresentado na página. O plug-in de DataTables é dependente de ID da tabela e as informações de cabeçalho armazenados em <thead>seção. Depois disso, um pouco de código percorre o IEnumerable <Title>passado para o modo de exibição do arquivo HomeController.cs e exibe os valores de nome, AverageRating e tempo de execução nas colunas apropriadas.

Quando a página inicialmente é inicializado, o método JavaScript na tag de cabeçalho usa jQuery para localizar a tabela Netflix no formulário e aplica a função de dataTable para ele. DataTables é altamente configurável, mas com esse formulário simple de chamar a função de dataTable, tabela de referência, Netflix, adquirirá a configuração padrão de DataTables. Figura 3 mostra a página resultante.

Figura 3 Exibindo dados com o plug-in de DataTables

DataTables fez mais do que usar CSS para tornar a tabela bastante. Observe que, no final, ele informa que ele recuperado 155 linhas. Por padrão, ele não paginação cliente começando em 10 entradas por página, embora o usuário pode escolher 25, 50 ou 100 entradas por página no menu suspenso. A caixa de pesquisa filtra os resultados com base nas suas descobertas em todas as colunas disponíveis na tabela. O usuário também pode clicar nas colunas de linha de cabeçalho para classificar os dados. Os conjunto de recursos plug-in é tão rico que há de DataTables mesmo plug-ins para o plug-in. Você pode aprender mais sobre como melhorar o padrão no datatables. NET Web site.

Ao consultar OData no lado do cliente

Nem sempre você tem a vantagem de trabalhar com um cliente API, portanto, será o vire para a tarefa mais desafiador de consultar a OData de Netflix no lado do cliente sem o benefício de uma das outras bibliotecas disponíveis (a biblioteca de cliente AJAX). Eu vai empregar o plug-in ao obter em torno de algumas das limitações impostas pelo serviço Netflix de DataTables. Você provavelmente ter essas mesmas limitações ao trabalhar com outros serviços de OData públicos também.

Para esta rodada, estou usando um aplicativo ASP.NET WebForms app, embora eu pode usar HTML antigo simples porque não estou usando qualquer um.NET Framework código nesta página. A pasta \media. neste aplicativo também será necessário, mas você não criar um proxy para o serviço, portanto, não é necessário usar o Add Service Reference.

A função de dataTable tem um método chamado sAjaxSource que irá recuperar automaticamente os dados da fonte de destino. Mas isso requer que os resultados sejam formatados de maneira específica. OData resultados não alinham com isso. Há uma postagem de blog excelente escrita por um desenvolvedor com sede na Califórnia, Jeff Morris, que demonstra a remodelagem resultados de OData em um interceptador de consulta de serviços de dados do WCF. Você pode ler a postagem em bit.ly/bMPzTH .

Em vez disso, usarei o AJAX para retornar o OData em sua forma nativa e, em seguida, preencha a tabela manualmente.

O corpo da página começa com a tabela e seu <theader>definido (novamente, exigida pelo DataTables), bem como um <tbody> vazio:

<body>
  <form id="form1" runat="server">
    <table id="Netflix" width="100%">
      <thead>
        <tr><th width="50%">Title</th>
            <th>Rating</th>
            <th>Runtime</th></tr>
      </thead>
      <tbody id="netflixBody"/>
    </table>
  </form>
</body>

A página tem várias funções: GetData, displayResults e uma função auxiliar para lidar com uma das deficiências atuais do serviço Netflix. Semelhante do.Biblioteca de cliente de rede para OData, há uma biblioteca de cliente AJAX que faz parte do Microsoft ASP.NET AJAX APIs. Aqui está um exemplo de documentação do AJAX de uma consulta de JavaScript OData aparência usando esta biblioteca:

function doQuery() {
var northwindService = new
Sys.Data.OpenDataServiceProxy("/Northwind.svc");
northwindService.query("/Customers", cbSuccess, cbFailure, userContext);

Como alternativa, você pode usar AJAX e jQuery reta quanto eu nos exemplos a seguir. Vamos dar uma olhada no início do script de cabeçalho, incluindo a função getData:

<script type="text/javascript" charset="utf-8">
  var oTable;
  var query = "http://odata.
netflix.com/v1/Catalog/Titles?$orderby=Name&$top=500"

  $(document).ready(function () { getData() });

  function getData() {
    var url = query + "&$callback= displayResults" 
      + "&$format=json";
    $.ajax({ dataType: "jsonp", url: url });
  }

Quando a página for iniciada, a função document.ready chama automaticamente getData. getData constrói uma URL da consulta OData predefinida e acrescenta parâmetros para retornar o OData como JSON (uma alternativa para o formato padrão de AtomPub), bem como a definição do método a ser executado quando a chamada AJAX for concluída.

Quando a chamada AJAX for concluída, a função displayResults será chamada usando os resultados da consulta OData (consulte a Figura 4 ).

Figura 4 OData resultados para exibição de preparação

function displayResults(results) {
  var entities;
  var redraw;

// Find data in results 
  if (results.d[0] == undefined) {
    queryNext = results.d.__next;
    entities = results.d.results;
  }
  else {
    queryNext = "";
    entities = results.d;
  }

  // Instantiate dataTable if necessary
  if (oTable ==null)
    oTable = $('#Netflix').dataTable();

  // Build table rows from data using dataTables.Add
  for (var post in entities) {
    if (post == queryResults.length-1)
      redraw = true; //only redraw table on last item
    else
      redraw = false;

    oTable.fnAddData([
      entities[post].Name, entities[post].Rating, 
      entities[post].Runtime],redraw);
  }

  // Continue retrieving results
  if (queryNext > "") {
    query = FixNetFlixUrl(queryNext);
    getData();
  }
}

A seção do código que comentou com "localizar dados nos resultados" está manipulando uma das limitações de Netflix que mencionei. Netflix está impondo a paginação do servidor para proteger seus servidores e retorna apenas 500 linhas por solicitação. Você pode imaginar se alguém ociosamente consultado para todos os filmes? Tenho certeza de que o que acontece com freqüência. A paginação do servidor não impede a navegação linhas adicionais;Basta fazer isso explicitamente.

Tratamento de grandes quantidades de dados no cliente é exatamente o que é brilhante em DataTables e há uma boa chance de que você vai querer tirar proveito dele. Pode demorar um pouco mais para carregar todos os dados quando você estiver recuperando grandes quantidades (por exemplo, 5000 linhas), mas que já estiverem na memória, DataTables pode permitir que o usuário final faça todos os tipos de filtragem e classificação de dados.

Quando vi primeiro DataTables demonstrado, a pessoa mostrá-lo disse que eles estavam ocupando-lo para uma ferramenta de relatórios corporativa onde eles foram baixando 80000 linhas. Eu alto Protestado a esse abuso da Internet e o servidor. No entanto, ter visto DataTables em ação, eu sou não são mais tão opposed para este uso em um cenário controlado.

OData fornece uma maneira para facilmente solicitar outro lote de dados e Netflix fornece esse gancho para você aproveitar. Aqui está uma consulta que solicita 501 resultados:

http://odata.
netflix.com/v1/Catalog/Titles?$orderby=Name&$top=501

Quando a consulta excede o limite do serviço, Netflix usa o recurso de token de continuação de OData. Além de entradas, os resultados contêm um elemento a mais após a última entrada. Aqui está no formato AtomPub:

<link rel="next"
  href="http://odata.
netflix.com:20000/v1/Catalog/Titles/?$orderby=
Name&$top=1&$skiptoken='1975%20Oklahoma%20National%20Championship%20
Game','BVZUb'" /> 
</feed>

O parâmetro skiptoken informa onde começar com o próximo conjunto de resultados de consulta. Em JSON, que a entrada é vista no início dos resultados em uma propriedade chamada __next, conforme mostrado no a Figura 5 .

Figura 5 resultados JSON de uma solicitação de mais dados do que o serviço está configurado para retorno

Quando uma consulta não excede o limite, as entradas são diretamente dentro da propriedade d, como você pode ver na a Figura 6 . É por isso que GetData precisará testar para ver onde ele irá encontrar os resultados. Se houver um token de continuação, ele armazena que nos NextQuery e, em seguida, executa a consulta de continuação para construir o completo conjunto de resultados na memória.

Figura 6 JSON resulta de uma solicitação dentro do período de retorno configurado

Se você examinar a propriedade __next, você perceberá que o Netflix adicionado a um número de porta, 20000, à consulta. No entanto, se você executar essa consulta diretamente, ele falhará. Portanto, você precisará remover o número da porta do URI antes de solicitar a ele. Essa é a finalidade da função FixNetFlixUrl que eu chamo antes de fazer a solicitação.

Você terá que aguardar anomalias, como quando o consumo de serviços públicos de OData. Agora você já viu como lidar com um serviço que limita o número de resultados, que ela retornará e outra que inflicts uma alteração significativa em seu token de continuação.

Para cada conjunto de resultados é recuperado, o método usa o método fnAddData de DataTables para adicionar cada item na tabela. Redesenhar a tabela é cara, portanto, defini o parâmetro de redesenho de fnAddData para false até atingir o último item nos resultados. Redesenhar durante a recuperação de dados torna a interface do usuário mais fluida, em vez de aguardar até que todas as linhas de 5 mil foram recuperadas e adicionadas à tabela.

Depois de modificar a consulta inicial para retornar a 5000 linhas em meu ambiente rural-Vermont-with-poky-Internet-access e adiando o redesenho de tela para o fim tive, levou aproximadamente um minuto para capturar todas as linhas e exibir a tabela. Redesenhar cada linha era muito mais fluida e fui capaz de interagir com a tabela, mesmo que estavam sendo adicionadas mais linhas. Isso foi uma boa surpresa.

Depois que todas as linhas de 5000 estavam na tabela, DataTables fez um trabalho incrível de classificação e pesquisa. Classificação levou menos de um segundo. Pesquisa foi instantânea, como ele responde a cada pressionamento de tecla na caixa de pesquisa (consulte a Figura 7 ).

Figura 7 resultados da pesquisa em tempo real em DataTables

Um pequeno ajuste para o Internet Explorer 8

Uma atualização recente DataTables aciona um recurso que é desejável nenhuma ao trabalhar com grande resultado define DataTables do Internet Explorer 8. Internet Explorer exibe uma mensagem de aviso quando muitas linhas de script estiver sendo executadas.

O site de suporte da Microsoft recomenda o ajuste do cliente do registro da máquina para alterar esse comportamento. Não é uma solução razoável para corrigir este aplicativo.Não quero mexer com configurações de registro do cliente se ele pode ser evitado. Mas há outra opção.

Uma postagem nos fóruns do usuário DataTables sugerida uma modificação no arquivo de script de DataTables. Implementei essa modificação e funciona muito bem. Você pode ver os detalhes no thread de fórum intitulado "Classificação faz com que o IE lançar 'um script desta página está causando o Internet Explorer execute lentamente,'" em bit.ly/co4AMD .

Tantos recursos a serem explorados

Espero que você já viu suficiente para compreender o Meu entusiasmo over nesse amplo plug-in. Há muito mais que você pode fazer para configurar a aparência da tabela — bem como seu comportamento — no cenário de somente leitura que demonstrei. DataTables também permite que você edite de forma fluida e se você quiser manter alguns essa lógica no lado do servidor, você pode fazer isso enquanto ainda se beneficia de DataTables.

Usando DataTables para permitir que seus usuários finais fatia e dos dados as grandes quantidades de dados disponíveis, o número crescente de serviços de OData publicamente disponíveis parece, para mim, uma correspondência feita no céu geek.

Julie Lerman é uma Microsoft MVP, mentora e consultora do .NET, que reside nas colinas de Vermont. Você pode encontrar a sua apresentação no acesso a dados e outro Microsoft.NET Framework tópicos em grupos de usuários e conferências em todo o mundo. Seu blog está em thedatafarm.com/blog e ela é autora do livro altamente reconhecido, “Programming Entity Framework” (O’Reilly Media, 2010). Siga a ela no Twitter.com: @julielerman .

Graças aos seguintes especialistas técnicos para revisão deste artigo: Rey Bango e Alex James