Introduction au développement de webOS SDK Partie 3

Bienvenue dans la troisième partie de notre série sur le développement de SDK webOS. Dans la partie 2, nous avons fourni des données statiques à une liste. Ce tutoriel vous montrera comment charger des données dynamiques dans une liste. Nous allons utiliser AJAX et YQL pour y parvenir.

Spinner et Scrim

Commençons par changer le code HTML de la scène de liste. Modifiez app / views / list / list-scene.html pour contenir les éléments suivants:

 

L'en-tête et la liste sont similaires à ceux de la scène principale. Ce que nous ajoutons, c'est un canevas et une roulette. Qu'est-ce qu'un canevas et une roulette que vous demandez? Une visionneuse affiche une image en rotation (surprise!) Comme une indication du fait qu'une opération est en cours. C'est un bon choix d'afficher un compteur pour chaque opération qui va prendre un certain temps (et rappelez-vous, puisque nous sommes sur un appareil mobile, les opérations qui obtiennent des données distantes via une connexion sans fil peuvent prendre un certain temps). De plus, nous utilisons un canevas (une couche translucide utilisée pour masquer l'interface utilisateur d'arrière-plan) pour masquer l'interface utilisateur d'arrière-plan pendant l'affichage du compteur car il ne serait pas logique d'interagir avec l'application pendant qu'une opération est en attente..

Nous ajoutons également une division enveloppante autour de notre liste pour la placer sous l'en-tête. Définissez la classe nécessaire dans stylesheet / tutsplus.css pour cela:

 .liste principale padding-top: 48px; 

Ensuite, rendez-vous sur app / assistants / list-assistant.js pour ajouter la logique de l'application. Nous définissons d’abord le modèle de liste. Contrairement à la dernière fois, où les données de modèle étaient statiques, notre modèle de liste ne contiendrait aucune donnée, il sera chargé dans la liste plus tard..

 this.myListModel = items: []; this.myListAttr = itemTemplate: "list / itemTemplate", renderLimit: 10, dividerTemplate: "list / dividerTemplate", dividerFunction: this.whatPosition;

List Divider

Nous définissons deux nouvelles propriétés dans nos attributs de liste cette fois-ci: dividerTemplate et dividerFunction. Laissez-moi expliquer les diviseurs en premier. Ce sont essentiellement des éléments placés entre des entrées de liste pour les regrouper. Dans notre application, nous voulons regrouper les articles affichés par date. Allez-y et créez la dividerFunction:

 ListAssistant.prototype.whatPosition = function (listitem) var myDate = new Date (listitem.pubdate); var ds = Mojo.Format.formatDate (myDate, date: "long", countryCode: "US"); renvoyer ds; 

Un listitem est transmis à notre fonction et nous créons un objet date javascript à partir de sa propriété pubDate (il fait référence à la date de publication obtenue du flux RSS). Nous reformatons ensuite cette date avec une fonction Mojo en une chaîne de date longue (par exemple, le 6 septembre 2010) et la renvoyons. La logique de liste utilisera ensuite cette date pour regrouper les éléments de la liste ayant la même date. Le dividerTemplate définit à quoi ressemble le diviseur réel. Éditez app / views / list / dividerTemplate.html:

 
# dividerLabel

Chaque fois que la liste affiche un diviseur, elle insère le code HTML ci-dessus en remplaçant # dividerLabel par la chaîne de date..

Permet de créer le modèle de liste ensuite, éditez app / views / list / itemTemplate.html:

 
#Catégoriepar # créateur
#Les données
#la description

De nouveau, nous spécifions comment chaque ligne de la liste est agencée et quelles données du modèle sont affichées. Ajoutez également les nouvelles classes aux stylesheets / tutsplus.css:

 .pubdate font-size: 10px;  .creator font-size: 12px; couleur de fond: # a0a0a0; Flotter à droite; rembourrage: 3px 3px; text-align: right; marge droite: 14px; marge supérieure: 4 px; Couleur blanche;  .ellipsis padding: 10px 0px; marge gauche: 14px; taille de police: 19px; largeur: 95%; débordement caché; espace blanc: maintenant; débordement de texte: points de suspension;  .descr font-size: 14px; marge gauche: 14px; largeur: 95%;  .button width: 95%; débordement caché; espace blanc: maintenant; débordement de texte: clip; marge gauche: 14px; rembourrage: 3px 3px; -webkit-border-radius: 8px; Couleur blanche; taille de police: 14px; texte-décoration: aucun; alignement vertical: milieu;  .Nettuts border-top: 1px solid # 4a9082; arrière-plan: # 2e6a60;  .Vectortuts background: # 19487e;  .Psdtuts background: # a51500;  .Activetuts background: # a5290a;  .Aetuts background: # 4a3a57;  .Cgtuts background: # 73434f;  .Phototuts border-top: 1px solid # 3297b5; arrière-plan: # 2e92b2;  .Audiotuts background: # 3d6b00 .Mobiletuts border-top: 1px solid # ffd200; arrière-plan: # d19c00; 

À la fin de la fonction de configuration, ajoutez la dernière pièce manquante, la configuration de la roulette:

 this.controller.setupWidget ("search_divSpinner", spinnerSize: "large", spinning: true); 

Notez que nous avons déjà défini la rotation, mais comme la DIV contenant le disque est cachée, nous ne verrons pas l'image du disque..

Très bien, passons à autre chose et modifions la fonction d'activation:

 ListAssistant.prototype.activate = function (event) / * place ici les gestionnaires d’événements qui ne devraient être effectifs que lorsque cette scène est active. Par exemple, les gestionnaires de clés qui observent le document * / this.headerTitleElement.innerHTML = ""this.getData ();

AJAX et YQL

Nous affichons l'image de titre et un appel à getData. Cela chargera les données que nous voulons afficher dans notre liste. Allez-y et ajoutez la fonction getData:

 ListAssistant.prototype.getData = function () $ ("search_divScrim"). Show ();

Avant d’obtenir les données, nous montrons la DIV contenant le disque. Nous allons montrer le compteur pendant que le chargement est en cours. Notre objectif est d'afficher les derniers messages du site tutsplus sélectionné dans notre liste. Chaque site tutsplus exporte ses derniers articles dans un flux RSS. Comment lisons-nous le flux RSS à utiliser dans notre application? Nous allons utiliser YQL, le compte Yahoo! Query Language est un langage expressif de type SQL qui vous permet d'interroger, de filtrer et de joindre des données via des services Web (http://developer.yahoo.com/yql/). Je n'entrerai pas dans les détails sur YQL ici, vous pouvez en lire plus sur les nettuts.

Voici comment nous obtenons les données de mobiletuts avec YQL:

 select * from rss où url = "http://feeds.feedburner.com/mobile-tuts-summary"

Utilisez la console YQL à l’adresse http://developer.yahoo.com/yql/console pour l’essayer. Sélectionnez JSON comme format de sortie. Voici le résultat (abrégé):

 "query": "count": "1", "created": "2010-09-07T08: 41: 32Z", "lang": "en-US", "résultats": "item": [ "titre": "Introduction au développement de SDK webOS: Partie 2", "lien": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/" , "commentaires": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/#comments", "pubDate": "lun., 30 août 2010 12: 00:40 +0000 "," créateur ":" Markus Leutwyler "," catégorie ": [" webOS "," webOS internet "," webOS rss "," webOS SDK "," webOS table vue "]," guid " : "isPermaLink": "false", "content": "http://mobile.tutsplus.com/?p=2392"]);

On dirait que nous pouvons utiliser la plupart de ces données pour les afficher dans notre liste. Comment pouvons-nous l'insérer dans notre liste, demandez-vous? AJAX est la réponse. Nous allons utiliser une requête AJAX pour appeler le service Web YQL. Puisque mobiletuts utilise un flux différent de celui des autres sites, nous devons modifier l'URL du flux manuellement..

 var feed = this.title.toLowerCase (); if (feed == 'mobiletuts') feed = "mobile-tuts-summary";  else feed = feed + '- summary'; 
 var query = "Sélectionnez * depuis rss où url =" http://feeds.feedburner.com/ "+ feed +" ""; var url = "http://query.yahooapis.com/v1/public/yql?q="+encodeURIComponent(query)+"&format=json"; var request = new Ajax.Request (url, méthode: 'get', asynchrone: true, evalJSON: "false", onSuccess: this.parseResult.bind (this), on0: fonction (ajaxResponse) // échec de la connexion, généralement parce que le serveur est surchargé ou est tombé en panne depuis le chargement de la page Mojo.Log.error ("Connexion échouée");, onFailure: function (réponse) // La requête a échoué (404, ce genre de chose) Mojo.Log .error ("Request failed");, onException: function (request, ex) // Une exception a été levée. Mojo.Log.error ("Exception");,); 

Nous utilisons la fonction Ajax.Request de Prototype pour appeler le service Web Yahoo. Les appels AJAX étant asynchrones, nous ne savons pas quand nous récupérerons les données du service Web. Nous spécifions la fonction à appeler lorsque les données sont reçues dans le rappel onSuccess: this.parseResult.bind (this)

Il y a quelque chose de nouveau dans la façon dont le rappel est appelé, notez la déclaration ajoutée .bind (this). Laissez-moi vous expliquer ce que "ceci" et cette portée en javascript signifient: En JavaScript, les fonctions sont exécutées dans un contexte spécifique, appelé "portée". Dans la fonction, le mot-clé this devient une référence à cette étendue. Par exemple, la variable this.title que nous utilisons dans la fonction getData est locale à cette fonction et ne sera pas disponible dans une autre fonction. Entrez .bind (this). "Binding" détermine essentiellement le sens du mot-clé "this" lorsqu'une fonction est exécutée. Dans notre exemple, lorsque nous appelons this.parseResult.bind (this), ses variables référencées par celle-ci sont disponibles dans la fonction parseResult..

Les données renvoyées par l'appel webservice se retrouvent dans l'objet de transport qui a été transmis à la fonction parseResult. Nous sommes intéressés par la propriété de texte transport.reponse, qui contient la sortie sous forme de chaîne JSON. Nous convertissons cela en objet en appelant evalJSON. Nous pouvons ensuite parcourir les propriétés des données JSON et collecter les données que nous voulons renseigner dans notre liste..

Analyse JSON

 ListAssistant.prototype.parseResult = function (transport) var newData = []; var data = transport.responseText; try var json = data.evalJSON ();  catch (e) Mojo.Log.error (e);  k = 0; pour (j = 0; j 

Étant donné que les catégories par article sont dynamiques, nous sortons simplement les 3 premières catégories des données JSON et construisons une nouvelle chaîne de catégorie (nommée cat). Nous devons également raccourcir la description, car le flux contient parfois des chaînes HTML que nous ne souhaitons pas afficher. Très bien, nous avons analysé notre réponse JSON et construit un nouveau tableau à partir de celui-ci. Ce tableau est la base de notre modèle de liste.

 this.myListModel ["items"] = newData; this.controller.modelChanged (this.myListModel, this); // cache le spinner $ ("search_divScrim"). hide (); ;

Tout d'abord, nous passons le tableau newData aux éléments de notre modèle de liste, puis nous notifions la liste avec laquelle un nouveau modèle est prêt à fonctionner. La liste affichera ensuite la liste avec les nouvelles données. Enfin, nous cachons notre casserole pour montrer à l'utilisateur que le processus de chargement est terminé.

Emballez l'application, installez-la et lancez-la. Pour chaque site tutsplus que vous sélectionnez, vous devriez maintenant voir la liste remplie avec les derniers articles..

Emballer

Toutes nos félicitations! Nous avons lu le contenu d'un flux RSS via YQL et avons ajouté ces données à notre liste. Dans la partie 4, nous allons ajouter la dernière pièce manquante à notre candidature.!