Welkom bij het derde deel van onze serie over webOS SDK-ontwikkeling. In deel 2 hebben we statische gegevens aan een lijst geleverd. In deze zelfstudie leert u hoe u dynamische gegevens in een lijst kunt laden. We gaan AJAX en YQL gebruiken om dit te bereiken.
Laten we beginnen met het veranderen van de HTML van de lijstscene. Bewerk app / views / list / list-scene.html om het volgende te bevatten:
De koptekst en lijst komen overeen met die in de hoofdscène. Wat we toevoegen is een scrim en een spinner. Wat is een scrim en een spinner die je vraagt? Een spinner toont een ronddraaiend (verrassing!) Beeld als een indicatie dat er een bewerking aan de gang is. Het is een goede keuze om een draaifunctie weer te geven voor elke bewerking die een tijdje gaat duren (en onthoud dat, aangezien we op een mobiel apparaat zijn, bewerkingen die externe gegevens via een draadloze verbinding ontvangen mogelijk enige tijd in beslag nemen). Daarnaast gebruiken we een scrim (een doorschijnende laag die wordt gebruikt om de achtergrond-UI te verbergen) om de achtergrond-UI te verbergen terwijl de spinner wordt weergegeven, omdat het geen zin zou hebben om met de toepassing te werken terwijl een bewerking in behandeling is.
We voegen ook een wikkelings-div toe rond onze lijst om deze onder de kop te duwen. Definieer de benodigde klasse in stylesheet / tutsplus.css daarvoor:
.hoofdlijst padding-top: 48px;
Ga vervolgens naar app / assistants / list-assistant.js om de toepassingslogica toe te voegen. Eerst definiëren we het lijstmodel. In tegenstelling tot de vorige keer, waar de modelgegevens statisch waren, bevat ons lijstmodel geen gegevens. Het wordt later in de lijst geladen.
this.myListModel = items: []; this.myListAttr = itemTemplate: "list / itemTemplate", renderLimit: 10, dividerTemplate: "list / dividerTemplate", dividerFunction: this.whatPosition;
We definiëren deze keer twee nieuwe eigenschappen in onze lijstattributen: dividerTemplate and dividerFunction. Laat me eerst de verdelers uitleggen. Het zijn in wezen elementen die tussen lijstinvoeren worden geplaatst om ze te groeperen. In onze app willen we de weergegeven artikelen groeperen op datum. Ga je gang en maak de dividerFunction aan:
ListAssistant.prototype.whatPosition = function (listitem) var myDate = new Date (listitem.pubdate); var ds = Mojo.Format.formatDate (myDate, date: "long", countryCode: "US"); return ds;
Een listitem wordt doorgegeven aan onze functie en we maken een javascript date-object uit zijn eigenschap pubDate (het verwijst naar de publicatiedatum die we van de RSS-feed krijgen). Vervolgens formatteren we die datum met een Mojo-functie naar een lange-datumreeks (bijvoorbeeld 6 september 2010) en retourneren we die. De logica van de lijst gebruikt die datum vervolgens om lijstitems samen te groeperen die dezelfde datum hebben. De dividerTemplate definieert hoe de feitelijke scheidingslijn er uitziet. Bewerk app / views / list / dividerTemplate.html:
# DividerLabel |
Elke keer dat de lijst een scheidingsteken bevat, wordt de bovenstaande HTML-code ingevoegd vervangt # dividerLabel door de datumreeks.
Laat de volgende lijstsjabloon maken, bewerk app / views / list / itemTemplate.html:
#categoriedoor # creator#gegevens#Omschrijving
Nogmaals, we specificeren hoe elke rij van de lijst is ingedeeld en welke gegevens van het model worden weergegeven. Voeg ook de nieuwe klassen toe aan de stylesheets / tutsplus.css:
.pubdate font-size: 10px; .creator font-size: 12px; achtergrondkleur: # a0a0a0; zweven: rechts; opvulling: 3px 3px; text-align: right; margin-right: 14px; margin-top: 4px; kleur wit; .ellipsis opvulling: 10px 0px; marge links: 14 px; lettertypegrootte: 19px; breedte: 95%; overloop verborgen; white-space: nowrap; tekstoverloop: ellips; .descr font-size: 14px; marge links: 14 px; breedte: 95%; .knop breedte: 95%; overloop verborgen; white-space: nowrap; tekstoverloop: clip; marge links: 14 px; opvulling: 3px 3px; -webkit-border-radius: 8px; kleur wit; lettergrootte: 14 px; tekstdecoratie: geen; vertical-align: middle; .Nuttuts border-top: 1px solid # 4a9082; achtergrond: # 2e6a60; .Vectortuts background: # 19487e; .Psdtuts background: # a51500; .Activetuts background: # a5290a; .Aututs background: # 4a3a57; .Cgtuts background: # 73434f; .Phototuts border-top: 1px solid # 3297b5; achtergrond: # 2e92b2; .Audiotuts background: # 3d6b00 .Mobiletuts border-top: 1px solid # ffd200; achtergrond: # d19c00;
Voeg aan het einde van de setup-functie het laatste ontbrekende stuk toe, de setup van de spinner:
this.controller.setupWidget ("search_divSpinner", spinnerSize: "large", spinning: true);
Merk op dat we het al laten draaien, maar omdat de DIV die de spinner bevat verborgen is, zullen we de spinner-afbeelding niet zien.
Oké, laten we doorgaan en de activeringsfunctie bewerken:
ListAssistant.prototype.activate = function (event) / * plaats hier event handlers die alleen van kracht zouden moeten zijn als deze scène actief is. Key handlers die bijvoorbeeld het document * / this.headerTitleElement.innerHTML = "observeren"this.getData ();
We tonen het titelbeeld en een aanroep van getData. Hiermee worden de gegevens geladen die we in onze lijst willen weergeven. Ga je gang en voeg de functie getData toe:
ListAssistant.prototype.getData = function () $ ("search_divScrim"). Show ();
Voordat we de gegevens ophalen, tonen we de DIV die de spinner bevat. We laten de draaifunctie zien terwijl de laadbewerking aan de gang is. Ons doel is om de nieuwste posts van de geselecteerde tutsplus-site in onze lijst weer te geven. Elke site van tutsplus exporteert de nieuwste artikelen in een RSS-feed. Hoe kunnen we de RSS-feed lezen die we in onze applicatie kunnen gebruiken? We gaan YQL gebruiken, de Yahoo! Query Language is een expressieve SQL-achtige taal waarmee u gegevens kunt doorzoeken, filteren en verbinden met verschillende webservices (http://developer.yahoo.com/yql/). Ik ga hier niet in op details over YQL, je kunt er meer over lezen op nettuts.
Zo krijgen we de gegevens van mobiletuts met YQL:
selecteer * uit rss waarbij url = "http://feeds.feedburner.com/mobile-tuts-summary"
Gebruik de YQL-console op http://developer.yahoo.com/yql/console om het uit te proberen. Selecteer JSON als uitvoerformaat. Hier is het (ingekorte) resultaat:
"query": "count": "1", "created": "2010-09-07T08: 41: 32Z", "lang": "en-US", "results": "item": [ "titel": "Inleiding tot webOS SDK-ontwikkeling: deel 2", "link": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/" , "comments": "http://mobile.tutsplus.com/tutorials/webos/introduction-to-webos-sdk-development-part-2/#comments", "pubDate": "Mon, 30 Aug 2010 12: 00:40 +0000 "," maker ":" Markus Leutwyler "," categorie ": [" webOS "," webOS internet "," webOS rss "," webOS SDK "," webOS tafelweergave "]," guid " : "isPermaLink": "false", "content": "http://mobile.tutsplus.com/?p=2392"]);
Het lijkt erop dat we de meeste van die gegevens kunnen gebruiken in onze lijst. Hoe krijgen we het in onze lijst, vraag je? AJAX is het antwoord. We gaan een AJAX-aanvraag gebruiken om de YQL-webservice te bellen. Omdat mobiletuts een andere feed gebruikt dan de andere sites, moeten we de feed-URL handmatig wijzigen.
var feed = this.title.toLowerCase (); if (feed == 'mobiletuts') feed = "mobile-tuts-summary"; else feed = feed + '- samenvatting';
var query = "Selecteer * from rss where url =" http://feeds.feedburner.com/ "+ feed +" ""; var url = "http://query.yahooapis.com/v1/public/yql?q="enencodeURIComponent(query)+"&format=json"; var request = new Ajax.Request (url, methode: 'get', asynchronous: true, evalJSON: "false", onSuccess: this.parseResult.bind (this), on0: function (ajaxResponse) // verbinding mislukt, meestal omdat de server overbelast is of is gedaald sinds de geladen pagina Mojo.Log.error ("Connection failed");, onFailure: function (response) // Verzoek mislukt (404, dat soort dingen) Mojo.Log .error ("Verzoek mislukt");, onException: function (request, ex) // Er is een uitzondering opgetreden Mojo.Log.error ("Exception");,);
We gebruiken de Ajax.Request-functie van Prototype om de Yahoo-webservice te bellen. Omdat AJAX-oproepen asynchroon zijn, weten we niet wanneer we de gegevens van de webservice terugkrijgen. We specificeren de functie die moet worden aangeroepen wanneer de gegevens worden ontvangen in de onSuccess-callback: this.parseResult.bind (this)
Er is iets nieuws in de callback, let op de toegevoegde statement .bind (this). Laat me uitleggen wat 'dit' en bereik in JavaScript betekent: in JavaScript worden functies uitgevoerd in een specifieke context, 'scope' genoemd. Binnen de functie wordt dit trefwoord een verwijzing naar dat bereik. De variabele this.title die we gebruiken in de functie getData is bijvoorbeeld lokaal voor die functie en zal niet beschikbaar zijn in een andere functie. Voer .bind in (dit). "Inbinden" bepaalt in feite de betekenis, wanneer een functie wordt uitgevoerd, van het "dit" sleutelwoord. In ons voorbeeld, wanneer we dit.parseResult.bind (dit) noemen, zijn de variabelen waarnaar hiernaar verwezen wordt, beschikbaar in de functie parseResult.
De geretourneerde gegevens van de webservice-oproep komen terecht in het transportobject dat is doorgegeven aan de functie parseResult. We zijn geïnteresseerd in de eigenschap transport.reponse Text, die de uitvoer als een JSON-tekenreeks bevat. We converteren dat naar een object door evalJSON te bellen. We kunnen dan de eigenschappen van de JSON-gegevens doorlopen en de gegevens verzamelen die we in onze lijst willen invullen.
ListAssistant.prototype.parseResult = function (transport) var newData = []; var data = transport.responseText; probeer var json = data.evalJSON (); catch (e) Mojo.Log.error (e); k = 0; voor (j = 0; jOmdat de categorieën per artikel dynamisch zijn, nemen we gewoon de eerste 3 categorieën uit de JSON-gegevens en bouwen er een nieuwe categorie-string uit (kat genaamd). We moeten ook de beschrijving verkorten, omdat de feed soms HTML-strings bevat die we niet willen weergeven. Goed, we hebben onze reactie JSON geparseerd en er een nieuwe array van gemaakt. Deze array vormt de basis voor ons lijstmodel.
this.myListModel ["items"] = newData; this.controller.modelChanged (this.myListModel, this); // verberg de spinner $ ("search_divScrim"). hide (); ;Eerst geven we de array newData door aan de items van ons lijstmodel en melden vervolgens aan de lijst dat er een nieuw model klaarstaat om mee te werken. De lijst zal dan de lijst met de nieuwe gegevens weergeven. Eindelijk verbergen we onze spinner om de gebruiker te laten zien dat het laadproces is beëindigd.
Pakket de app, installeer en voer het uit. Voor elke tutsplus-site die u selecteert, ziet u nu dat de lijst wordt gevuld met de nieuwste artikelen.
Afronden
Gefeliciteerd! We hebben de inhoud van een RSS via YQL gelezen en die gegevens in onze lijst ingevoerd. In deel 4 gaan we het laatste ontbrekende stuk toevoegen aan onze applicatie!