Benvenuti alla terza parte della nostra serie sullo sviluppo di SDK webOS. Nella parte 2, abbiamo fornito dati statici a un elenco. Questo tutorial ti mostrerà come caricare dati dinamici in un elenco. Useremo AJAX e YQL per raggiungere questo obiettivo.
Iniziamo cambiando l'HTML della scena elenco. Modifica app / views / list / list-scene.html per contenere quanto segue:
L'intestazione e l'elenco sono simili a quelli nella scena principale. Quello che stiamo aggiungendo è uno scrim e uno spinner. Che cos'è uno scrim e uno spinner che chiedi? Uno spinner mostra un'immagine rotante (sorpresa!) Come un'indicazione che un'operazione è in corso. È una buona scelta per visualizzare uno spinner per ogni operazione che richiederà un po '(e ricorda, dal momento che siamo su un dispositivo mobile, le operazioni che ottengono i dati remoti tramite una connessione wireless potrebbero richiedere del tempo). Inoltre, utilizziamo uno scrim (uno strato traslucido utilizzato per oscurare l'interfaccia utente di sfondo) per nascondere l'interfaccia utente di sfondo mentre viene visualizzato lo spinner perché non avrebbe senso interagire con l'applicazione mentre un'operazione è in sospeso.
Aggiungiamo anche un div wrapping alla nostra lista per spingerlo sotto l'intestazione. Definisci la classe necessaria in stylesheet / tutsplus.css per questo:
.main-list padding-top: 48px;
Quindi, vai su app / assistants / list-assistant.js per aggiungere la logica dell'applicazione. Per prima cosa definiamo il modello di lista. Diversamente dall'ultima volta, in cui i dati del modello erano statici, il nostro listmodel non ha alcun dato in esso - verrà caricato nella lista in un secondo momento.
this.myListModel = items: []; this.myListAttr = itemTemplate: "list / itemTemplate", renderLimit: 10, dividerTemplate: "list / dividerTemplate", dividerFunction: this.whatPosition;
Definiamo due nuove proprietà negli attributi della nostra lista questa volta: dividerTemplate e dividerFunction. Lasciatemi spiegare prima i divisori. Sono essenzialmente elementi messi tra le voci dell'elenco per raggrupparli. Nella nostra app vogliamo raggruppare gli articoli visualizzati per data. Vai avanti e crea la funzione divisore:
ListAssistant.prototype.whatPosition = function (listitem) var myDate = new Date (listitem.pubdate); var ds = Mojo.Format.formatDate (myDate, date: "long", countryCode: "US"); return ds;
Un listino è passato alla nostra funzione e creiamo un oggetto data javascript fuori dalla sua proprietà pubDate (si riferisce alla data di pubblicazione che otteniamo dal feed RSS). Quindi riformattiamo quella data con una funzione Mojo su una stringa di data lunga (ad esempio, 6 settembre 2010) e la restituiamo. La logica dell'elenco utilizzerà quindi quella data per raggruppare insieme le voci dell'elenco che hanno la stessa data. Il divisoreTemplate definisce come appare il divisore effettivo. Modifica app / visualizzazioni / elenco / dividerTemplate.html:
# DividerLabel |
Ogni volta che la lista esegue il rendering di un divisore, inserisce il codice HTML sopra in sostituzione di # dividerLabel con la stringa della data.
Consente di creare il modello elenco successivo, modifica app / visualizzazioni / elenco / articoloTemplate.html:
#categoriadi # creatore#dati#descrizione
Ancora una volta, specifichiamo come è disposta ogni riga della lista e quali dati del modello sono visualizzati. Aggiungi anche le nuove classi a stylesheets / tutsplus.css:
.pubdate font-size: 10px; .creator font-size: 12px; background-color: # a0a0a0; float: giusto; imbottitura: 3px 3px; allineamento del testo: giusto; margin-right: 14px; margin-top: 4px; colore bianco; .ellipsis padding: 10px 0px; margin-left: 14px; dimensione carattere: 19px; larghezza: 95%; overflow: nascosto; white-space: nowrap; overflow del testo: ellissi; .descr font-size: 14px; margin-left: 14px; larghezza: 95%; .button width: 95%; overflow: nascosto; white-space: nowrap; overflow del testo: clip; margin-left: 14px; imbottitura: 3px 3px; -webkit-border-radius: 8px; colore bianco; font-size: 14px; decorazione del testo: nessuna; allineamento verticale: medio; . Nettuts border-top: 1px solid # 4a9082; sfondo: # 2e6a60; .Vectortuts background: # 19487e; .Psdtuts background: # a51500; . Attivi background: # a5290a; .Aututs background: # 4a3a57; .Cgtuts background: # 73434f; .Phototuts border-top: 1px solid # 3297b5; sfondo: # 2e92b2; .Audiotuts background: # 3d6b00 .Mobiletuts border-top: 1px solid # ffd200; sfondo: # d19c00;
Alla fine della funzione di setup, aggiungi l'ultimo pezzo mancante, la configurazione dello spinner:
this.controller.setupWidget ("search_divSpinner", spinnerSize: "large", spinning: true);
Nota che lo abbiamo già impostato per girare, ma poiché il DIV contenente lo spinner è nascosto, non vedremo l'immagine dello spinner.
Bene, procediamo e modifichiamo la funzione di attivazione:
ListAssistant.prototype.activate = function (event) / * metti qui i gestori di eventi che dovrebbero essere attivi solo quando questa scena è attiva. Ad esempio, i gestori di chiavi che stanno osservando il documento * / this.headerTitleElement.innerHTML = ""this.getData ();
Visualizziamo l'immagine del titolo e una chiamata a getData. Questo caricherà i dati che vogliamo visualizzare nella nostra lista. Vai avanti e aggiungi la funzione getData:
ListAssistant.prototype.getData = function () $ ("search_divScrim"). Show ();
Prima di ottenere i dati, mostriamo il DIV contenente lo spinner. Mostreremo lo spinner mentre è in corso l'operazione di caricamento. Il nostro obiettivo è quello di visualizzare nel nostro elenco i post più recenti del sito tutsplus selezionato. Ogni sito tutsplus esporta i suoi ultimi articoli in un feed RSS. Come leggiamo il feed RSS da utilizzare nella nostra applicazione? Useremo YQL, l'Yahoo! Il linguaggio di query è un linguaggio espressivo simile a SQL che consente di eseguire query, filtrare e unire i dati tra i servizi Web (http://developer.yahoo.com/yql/). Non entrerò nei dettagli di YQL qui, puoi leggere di più su Nets.
Ecco come otteniamo i dati da mobiletuts con YQL:
seleziona * da rss dove url = "http://feeds.feedburner.com/mobile-tuts-summary"
Usa la console YQL su http://developer.yahoo.com/yql/console per provarlo. Seleziona JSON come formato di output. Ecco il risultato (abbreviato):
"query": "count": "1", "created": "2010-09-07T08: 41: 32Z", "lang": "en-US", "results": "item": [ "title": "Introduzione a webOS SDK Development: Part 2", "link": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/" , "commenti": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/#comments", "pubDate": "Mon, 30 ago 2010 12: 00:40 +0000 "," creatore ":" Markus Leutwyler "," categoria ": [" webOS "," webOS internet "," webOS rss "," webOS SDK "," webOS table view "]," guid " : "isPermaLink": "false", "content": "http://mobile.tutsplus.com/?p=2392"]);
Sembra che possiamo usare la maggior parte di quei dati da visualizzare nel nostro elenco. Come lo inseriamo nella nostra lista, chiedi? AJAX è la risposta. Utilizzeremo una richiesta AJAX per chiamare il servizio web YQL. Poiché mobiletut utilizza un feed diverso rispetto agli altri siti, è necessario modificare manualmente l'URL del feed.
var feed = this.title.toLowerCase (); if (feed == 'mobiletuts') feed = "mobile-tuts-summary"; else feed = feed + '- summary';
var query = "Seleziona * da rss dove 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, metodo: 'get', asincrono: true, evalJSON: "false", onSuccess: this.parseResult.bind (this), on0: function (ajaxResponse) // connection failed, in genere perché il server è sovraccarico o è andato giù da quando la pagina ha caricato Mojo.Log.error ("Connessione fallita");, onFailure: function (response) // Richiesta fallita (404, quel genere di cose) Mojo.Log .error ("Richiesta non riuscita");, onException: function (request, ex) // È stata generata un'eccezione Mojo.Log.error ("Exception");,);
Stiamo utilizzando la funzione Ajax.Request di Prototype per chiamare il webservice di Yahoo. Dal momento che le chiamate AJAX sono asincrone, non sappiamo quando recuperiamo i dati dal webservice. Specifichiamo la funzione da chiamare quando i dati vengono ricevuti nel callback onSuccess: this.parseResult.bind (this)
C'è qualcosa di nuovo nel modo in cui viene richiamato il callback, si noti la dichiarazione aggiunta .bind (this). Lasciatemi spiegare cosa "questo" e lo scope in javascript significano: In JavaScript, le funzioni sono eseguite in un contesto specifico, denominato "scope". All'interno della funzione, questa parola chiave diventa un riferimento a tale ambito. Ad esempio, la variabile this.title che stiamo utilizzando nella funzione getData è locale per quella funzione e non sarà disponibile in un'altra funzione. Inserisci .bind (questo). "Binding" determina fondamentalmente il significato, quando una funzione viene eseguita, della parola chiave "this". Nel nostro esempio, quando chiamiamo this.parseResult.bind (this), le variabili a cui è stato fatto riferimento tramite questo sono disponibili nella funzione parseResult.
I dati restituiti dalla chiamata al servizio Web si concludono nell'oggetto trasporto che è passato alla funzione parseResult. Siamo interessati alla proprietà di testo transport.reponse, che contiene l'output come stringa JSON. Lo convertiamo in un oggetto chiamando evalJSON. Possiamo quindi scorrere le proprietà dei dati JSON e raccogliere i dati che vogliamo compilare nel nostro elenco.
ListAssistant.prototype.parseResult = function (transport) var newData = []; var data = transport.responseText; prova var json = data.evalJSON (); catch (e) Mojo.Log.error (e); k = 0; per (j = 0; jPoiché le categorie per articolo sono dinamiche, stiamo semplicemente prendendo le prime 3 categorie dai dati JSON e costruiamo una nuova stringa di categoria (denominata cat). Dobbiamo anche abbreviare la descrizione, perché a volte il feed contiene stringhe HTML che non vogliamo visualizzare. Bene, abbiamo analizzato la nostra risposta JSON e ne abbiamo costruito una nuova serie. Questo array è la base per il nostro modello di lista.
this.myListModel ["items"] = newData; this.controller.modelChanged (this.myListModel, this); // nasconde lo spinner $ ("search_divScrim"). hide (); ;Per prima cosa, passiamo la matrice newData agli elementi del nostro modello di lista e poi notificiamo l'elenco che c'è un nuovo modello pronto per funzionare. L'elenco mostrerà quindi la lista con i nuovi dati. Alla fine, nascondiamo la nostra selezione per mostrare all'utente che il processo di caricamento è terminato.
Imballa l'app, installala ed eseguila. Per ogni sito tutsplus selezionato, ora dovresti vedere la lista popolata con gli ultimi articoli.
Incartare
Congratulazioni! Abbiamo letto il contenuto di un RSS tramite YQL e abbiamo inserito tali dati nella nostra lista. Nella parte 4 aggiungeremo l'ultimo pezzo mancante alla nostra applicazione!