Velkommen til den tredje delen av serien vår på webOS SDK-utvikling. I del 2 ga vi statiske data til en liste. Denne opplæringen viser deg hvordan du laster inn dynamiske data i en liste. Vi skal bruke AJAX og YQL for å oppnå dette.
La oss begynne med å endre listescenenes HTML. Rediger app / visninger / liste / list-scene.html for å inneholde følgende:
Overskriften og listen ligner de i hovedscenen. Det vi legger til er en scrim og en spinner. Hva er en scrim og en spinner du spør? En spinner viser et spinning (overraskelse!) Bilde som en indikasjon på at en operasjon pågår. Det er et godt valg å vise en spinner for hver operasjon som skal ta en stund (og husk, siden vi er på en mobil enhet, kan operasjoner som får fjerndata over en trådløs tilkobling kanskje ta en stund). I tillegg bruker vi en scrim (et gjennomsiktig lag som brukes til å skjule bakgrunnsgrensesnittet) for å skjule bakgrunnsgrensesnittet mens spinneren vises, fordi det ikke ville være fornuftig å samhandle med programmet mens en operasjon er ventet.
Vi legger også til en wrapping div rundt vår liste for å trykke den ned under overskriften. Definer den nødvendige klassen i stilark / tutsplus.css for det:
.hovedliste padding-top: 48px;
Deretter går du over til app / assistenter / list-assistant.js for å legge til programlogikken. Først definerer vi listemodellen. I motsetning til forrige gang, hvor modelldataene var statiske, vil vår listemodell ikke ha noen data i den - det vil bli lastet inn i listen senere.
this.myListModel = elementer: []; this.myListAttr = itemTemplate: "list / itemTemplate", renderLimit: 10, dividerTemplate: "list / dividerTemplate", dividerFunction: this.whatPosition;
Vi definerer to nye egenskaper i våre listattributter denne gangen: dividerTemplate og dividerFunction. La meg forklare divider først. De er i hovedsak elementer som legges mellom listeposter for å gruppere dem. I vår app vil vi gruppere de viste artiklene etter dato. Gå videre og opprett dividerFunction:
ListAssistant.prototype.whatPosition = funksjon (listitem) var myDate = new Date (listitem.pubdate); var ds = Mojo.Format.formatDate (myDate, date: "long", countryCode: "US"); retur ds;
En liste er sendt til vår funksjon, og vi oppretter et javascript dateobjekt ut av sin pubDate-eiendom (det refererer til publiseringsdatoen vi kommer fra RSS-feedet). Vi formaterer deretter datoen med en Mojo-funksjon til en lang datostreng (f.eks. 6. september 2010) og returnerer det. Listen logikken vil da bruke den datoen til å gruppere gruppeposter sammen som har samme dato. DividerTemplate definerer hvordan den faktiske skillelinjen ser ut. Rediger app / visninger / liste / dividerTemplate.html:
# DividerLabel |
Hver gang listen gjør en divider, legger den inn HTML-koden ovenfor i erstatter # dividerLabel med datastrengen.
Lar oss opprette listemalen neste, rediger app / visninger / liste / elementTemplate.html:
#kategoriav # skaperen#data#beskrivelse
Igjen spesifiserer vi hvordan hver rad i listen er lagt ut og hvilke data på modellen som vises. Legg også til de nye klassene i stilarkene / tutsplus.css:
.pubdate font-size: 10px; .creator font-size: 12px; bakgrunnsfarge: # a0a0a0; flyte: høyre; polstring: 3px 3px; tekstjustering: høyre; margin-høyre: 14px; margin-topp: 4px; farge: hvit; .ellipsis polstring: 10px 0px; margin-venstre: 14px; skriftstørrelse: 19px; bredde: 95%; overløp: skjult; hvit-rom: nowrap; tekstoverløp: ellipsis; .descr font-size: 14px; margin-venstre: 14px; bredde: 95%; . knapp bredde: 95%; overløp: skjult; hvit-rom: nowrap; tekstoverløp: klipp; margin-venstre: 14px; polstring: 3px 3px; -webkit-grense-radius: 8px; farge: hvit; skriftstørrelse: 14px; tekst-dekorasjon: ingen; vertikaljustering: midt; .Nettuts border-top: 1px solid # 4a9082; bakgrunn: # 2e6a60; .Vectortuts bakgrunn: # 19487e; .Psdtuts bakgrunn: # a51500; . Aktivitetsutskrifter bakgrunn: # a5290a; .Aetuts bakgrunn: # 4a3a57; .Cgtuts bakgrunn: # 73434f; .Phototuts border-top: 1px solid # 3297b5; bakgrunn: # 2e92b2; .Audiotuts bakgrunn: # 3d6b00 .Mobiletuts border-top: 1px solid # ffd200; bakgrunn: # d19c00;
På slutten av oppsettfunksjonen, legg til det siste manglende stykket, oppsettet av spinneren:
this.controller.setupWidget ("search_divSpinner", spinnerSize: "large", spinning: true);
Legg merke til at vi satte det til å spinne allerede, men fordi DIV-spinneren er skjult, ser vi ikke spinnerbildet.
OK, la oss gå videre og redigere aktiveringsfunksjonen:
ListAssistant.prototype.activate = function (event) / * sett inn hendelseshåndterere her som bare skal være i kraft når denne scenen er aktiv. For eksempel, nøkkelbehandlere som observerer dokumentet * / this.headerTitleElement.innerHTML = ""this.getData ();
Vi viser tittelbildet og en samtale til getData. Dette vil laste inn dataene vi vil vise i vår liste. Gå videre og legg til funksjonen getData:
ListAssistant.prototype.getData = function () $ ("search_divScrim"). Show ();
Før vi får dataene, viser vi DIV som inneholder spinner. Vi viser spinneren mens lastoperasjonen pågår. Vårt mål er å vise de siste innleggene fra det valgte tutsplus-nettstedet til vår liste. Hver tutsplus-side eksporterer sine nyeste artikler i et RSS-feed. Hvordan leser vi RSS-feedet som skal brukes i vår søknad? Vi skal bruke YQL, Yahoo! Query Language er et ekspressivt SQL-lignende språk som lar deg spørre, filtrere og delta i data på tvers av webtjenester (http://developer.yahoo.com/yql/). Jeg vil ikke gå inn i detaljer om YQL her, du kan lese mer om det på nett.
Slik får vi dataene fra mobiletuts med YQL:
velg * fra rss hvor url = "http://feeds.feedburner.com/mobile-tuts-summary"
Bruk YQL-konsollen på http://developer.yahoo.com/yql/console for å prøve den ut. Velg JSON som utgangsformat. Her er resultatet (forkortet):
"count": "1", "created": "2010-09-07T08: 41: 32Z", "lang": "en-US", "resultater": "item": [ "title": "Introduksjon til webOS SDK Development: Del 2", "link": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/" , "kommentarer": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/#comments", "pubDate": "ma, 30 aug 2010 12: 00:40 +0000 "," skaperen ":" Markus Leutwyler "," kategori ": [" webOS "," webOS internet "," webOS rss "," webOS SDK "," webOS tabellvisning "]," guid " : "isPermaLink": "false", "content": "http://mobile.tutsplus.com/?p=2392"]);
Det ser ut til at vi kan bruke mesteparten av dataene til å vises i vår liste. Hvordan får vi det inn i vår liste, spør du? AJAX er svaret. Vi skal bruke en AJAX-forespørsel for å ringe til YQL webservice. Siden mobiletuts bruker en annen feed enn de andre nettstedene, må vi endre feedadressen manuelt.
var feed = this.title.toLowerCase (); hvis (feed == 'mobiletuts') feed = "mobile-tuts-summary"; annet feed = feed + '- summary';
var query = "Velg * fra rss der 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, metode: 'get', asynkron: true, evalJSON: "false", onSuccess: this.parseResult.bind (denne), on0: funksjon (ajaxResponse) vanligvis fordi serveren er overbelastet eller har gått ned siden siden lastet inn Mojo.Log.error ("Connection failed");, onFailure: funksjon (svar) // Forespørsel mislyktes (404, den slags ting) Mojo.Log .error ("Request failed");, onException: funksjon (forespørsel, ex) // Et unntak ble kastet Mojo.Log.error ("Exception");,);
Vi bruker prototypes Ajax.Request-funksjon for å ringe til Yahoo webservice. Siden AJAX-anrop er asynkron, vet vi ikke når vi får tilbake dataene fra webservice. Vi spesifiserer funksjonen som skal ringes når dataene mottas i onSuccess-tilbakeringingen: this.parseResult.bind (dette)
Det er noe nytt i hvordan tilbakekallingen blir kalt, legg merke til den ekstra setningen .bind (dette). La meg forklare hva "dette" og omfanget i javascript betyr: I JavaScript utføres funksjoner i en bestemt kontekst, referert til som "omfang". Innenfor funksjonen blir dette søkeordet en referanse til dette omfanget. For eksempel er variabelen this.title som vi bruker i funksjonen getData lokal til den funksjonen og vil ikke være tilgjengelig i en annen funksjon. Skriv inn .bind (dette). "Binding" bestemmer i utgangspunktet betydningen, når en funksjon kjører, av "dette" søkeordet. I vårt eksempel, når vi kaller this.parseResult.bind (dette), er variabler som ble referert gjennom dette, tilgjengelige i parseResult-funksjonen.
Dataene som returneres fra webservicesamtalen, avsluttes i transportobjektet som passerte til parseResult-funksjonen. Vi er interessert i texten Transport.reponse, som inneholder utdata som en JSON-streng. Vi konverterer det til et objekt ved å ringe evalJSON. Vi kan da gå gjennom egenskapene til JSON-dataene og samle inn dataene som vi vil fylle ut i vår liste.
ListAssistant.prototype.parseResult = funksjon (transport) var newData = []; var data = transport.responseText; prøv var json = data.evalJSON (); fangst (e) Mojo.Log.error (e); k = 0; for (j = 0; jSiden kategoriene per artikkel er dynamiske, tar vi bare de tre første kategoriene ut av JSON-dataene og bygger en ny kategoristreng ut av den (kalt navn). Vi må også forkorte beskrivelsen, fordi strømmen noen ganger inneholder HTML-strenger som vi ikke vil vise. Ok, vi har analysert vårt svar JSON og konstruert et nytt utvalg ut av det. Denne gruppen er grunnlaget for vår listemodell.
this.myListModel ["items"] = newData; this.controller.modelChanged (this.myListModel, dette); // skjul spinneren $ ("search_divScrim"). skjul (); ;Først sender vi matrisen NewData til elementene i vår listemodell, og merker deretter listen at det er en ny modell klar til å jobbe med. Listen vil da gjengi listen med de nye dataene. Til slutt skjuler vi spinneren vår for å vise brukeren at lastingsprosessen er avsluttet.
Pakke appen, installer og kjør den. For hvert tutsplus nettsted du velger, bør du nå se listen som er fylt med de nyeste artiklene.
Wrap up
Gratulerer! Vi har lest innholdet i en RSS gjennom YQL og matet disse dataene inn i vår liste. I del 4 kommer vi til å legge til det siste borte stykket i vår søknad!