Bibliothèque JavaScript datajs, une de plus ?
Disponible sur la forge Codeplex sous licence libre MIT depuis quelques mois, le projet datajs est une nouvelle bibliothèque JavaScript multi-navigateurs. Une de plus, nous direz-vous ! Vous utilisez par exemple déjà peut être aujourd’hui la bibliothèque jQuery. Dès lors, de légitimes questions comme « Quelles sont les similitudes ou différences ? », « Comment choisir entre les deux ? », etc. viennent à l’esprit.
La réponse est en fait assez simple, comme l’idée de datajs est de se focaliser sur l’apport de nouvelles fonctionnalités spécifiques. Datajs se concentre, en effet (sans surprise compte tenu de son nom), sur la manipulation de données. Cette bibliothèque n’est pas dénuée d’intérêts et vise des objectifs particuliers très intéressants : elle permet de concevoir des applications Web orientées données tirant bénéfices de protocoles modernes comme OData et des fonctionnalités de navigateurs autorisant la prise en charge de HTML5 comme le stockage local HTML5, IndexDB, etc.
Comme nous l’avons vu dans un précédent billet, le protocole ouvert de données OData fondé sur http en REST permet de requêter, filtrer, paginer, trier des données mais aussi modifier et supprimer ces mêmes données via une simple URI. Si la requête est une URI, la réponse est un flux de données Atom ou JSON.
Cette bibliothèque offre donc à la base des fonctionnalités pour communiquer avec des services OData, avec une prise en charge des formats Atom et JSON. L’API permet de s’appuyer sur un cache de données, de consommer les métadonnées exposées (ou de les déclarer statiquement) et de les utiliser pour améliorer les résultats, de grouper les opérations afin de minimiser les aller-retours via un traitement par lot des requêtes/réponses, de lisser les différences de format et de versions, etc.
Cette bibliothèque est conçue pour être compacte, performante, facile d’utilisation et pour fournir une fonctionnalité centrale qui permet à des applications Web d’être des citoyens de première classe vis-à-vis des données ouvertes Web. Elle ne s’intéresse pas aux interactions avec le DOM (X)HTML. De très bonnes bibliothèques JavaScript existent déjà comme jQuery en particulier.
jQuery permet en effet de son côté de vous affranchir des différences entre les API des navigateurs, de manipuler la structure de la page, de réaliser des animations, de prendre en charge des contrôles plus riches et de simplifier enfin l'accès au réseau, AJAX étant par exemple pris en charge.
Même s’il est possible de requêter un service OData avec un appel du type :
$.ajax({
dataType: "jsonp",
url: queryUri,
jsonpCallback: "callback",
success: callback
});
Ces deux bibliothèques répondent de fait à des objectifs différents. De cette façon, vous pouvez utiliser l'une ou l'autre ou les deux, selon ce que vous essayez de faire.
Nous profitons de la disponibilité hier d’une nouvelle version de cette bibliothèque pour vous en proposer une illustration rapide en termes de code afin que chacun puisse se faire rapidement une idée de la façon dont datajs peut être implémentée pour tirer bénéfice des ensembles de données exposés par le service de données OGDI.
Pour découvrir plus en détail les diverses fonctionnalités disponibles dans datajs, nous vous invitons à visionner la session MIX11 Data in HTML5 world.
Le site de test OGDI France met à disposition une interface OData pour permettre aux développeurs de tirer parti d’ensembles de données hébergés dans l'infrastructure Windows Azure dans le Cloud. Il propose différents ensembles de données prêts à l’usage comme celui des sanisettes installées dans Paris mis en avant par l’avis aux développeurs lancé sur le blog worldopendata ; les données correspondantes ayant été reprises du site OpenData ParisData de la Mairie de Paris.
Notre ambition (limitée) est ici simplement d’afficher la liste des sanisettes à partir l’URI correspondante sur OGDI France : https://ogdifrancedataservice.cloudapp.net/v1/frOpenData/Sanisettes. Cela suppose de commencer par télécharger la dernière version 0.0.4 et de référencer cette bibliothèque dans une page.
(Si vous utilisez Visual Studio, vous pouvez utiliser l’extension NuGet qui facilite l’ajout, la suppression et la mise à jour de bibliothèques et d’outils dans les projets Visual Studio en réalisant les modifications associées nécessaires telles que l'ajout de références et la modification du fichier web.config.)
Ensuite, le code suivant inspiré des nombreux exemples de la documentation datajs permet d’afficher la liste souhaitée.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<script src="datajs-0.0.4.min.js" type="text/javascript"></script>
<script type="text/javascript">
var uri = "https://ogdifrancedataservice.cloudapp.net/v1/frOpenData/Sanisettes";
OData.defaultHttpClient.enableJsonpCallback = true;
OData.defaultHttpClient.formatQueryString = "format=json";
OData.defaultHttpClient.callbackParameterName = "callback=handleJSONP_0"
OData.read(
uri
, function (data, response) {
var html = "";
for (var i = 0; i < data.results.length; i++) {
html += "<div>" + data.results[i].adresse + " " +
data.results[i].arrondissement + "</div>"
}
document.getElementById("SanisetteListContainer").innerHTML = html;
}
, function (err) {
alert("Une erreur s'est produite : " + err.message);
});
</script>
<title>Paris - Sanisettes</title>
</head>
<body>
<h1 class="title-regular">Liste</h1>
<div id="SanisetteListContainer">
<%-- data results will be placed here --%>
</div>
</body>
</html>
Deux remarques sont cependant nécessaires dans le contexte d’OGDI. De façon à retourner une réponse au format JSON, le service de données OGDI utilise comme nom d’argument 'format' plutôt que '$format' comme ajouté par défaut par datajs. La ligne suivante dans le code précédent permet de préciser ce point.
OData.defaultHttpClient.formatQueryString = "format=json";
Il en est de même pour l’utilisation de JSONP avec l’argument ‘callback' :
OData.defaultHttpClient.callbackParameterName = "callback=handleJSONP_0"
La fonction handleJSONP_0() est la fonction de callback JSONP utilisée par datajs.
Nous évoquions juste avant la possibilité de tirer quelques bénéfices d’une utilisation conjointe de datajs et de jQuery.
Le code suivant utilise de façon conjointe la notion de modèles (template) jQuery. Un modèle contient le balisage (X)HTML avec des expressions de liaison. Le modèle est ici appliqué à des entités issues de datajs et rendu dans le DOM (X)HTML.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<script src=" datajs-0.0.4.min.js" type="text/javascript"></script>
<script src="jquery-1.6.1.js" type="text/javascript"></script>
<script src="jQuery.tmpl.min.js" type="text/javascript"></script>
<!-- Sanisette Template -->
<script id="SanisetteTemplate" type="x-jquery-tmpl">
<tbody>
<tr>
<td>Adresse</td>
<td>Arrondissement</td>
</tr>
{{each sanisetteCollection }}
<tr>
<td>${adresse}</td>
<td>${arrondissement}</td>
</tr>
{{/each}}
</tbody>
</script>
<script type="text/javascript">
var uri="https://ogdifrancedataservice.cloudapp.net/v1/frOpenData/Sanisettes"
OData.defaultHttpClient.enableJsonpCallback = true;
OData.defaultHttpClient.formatQueryString = "format=json";
OData.defaultHttpClient.callbackParameterName="callback=handleJSONP_0"
OData.read(
uri
, function (data, response) {
$("#SanisetteListTemplateContainer").empty();
/* Render the SanisetteTemplate template with the
returnedSanisetteCollection data and insert the
rendered HTML under the
"SanisetteListTemplateContainer" element */
var returnedSanisetteCollection = data.results;
$("#SanisetteTemplate").tmpl({ sanisetteCollection: returnedSanisetteCollection }).
appendTo("#SanisetteListTemplateContainer");
}
, function (err) {
alert("Une erreur s'est produite : " + err.message);
});
</script>
<title>Paris - Sanisettes</title>
</head>
<body>
<h1 class="title-regular">Liste</h1>
<table id="SanisetteListTemplateContainer" class="GridView">
<%-- returnedSanisetteCollection data will be placed here --%>
</table>
</body>
</html>