Come personalizzare dati di modelli di Visual Studio (HTML)
[ Questo articolo è rivolto agli sviluppatori per Windows 8.x e Windows Phone 8.x che realizzano app di Windows Runtime. Gli sviluppatori che usano Windows 10 possono vedere Documentazione aggiornata ]
Nei modelli Hub/Pivot, Hub, Pivot, Grid e Split il codice che ottiene i dati necessari per l'app è nel file data.js. Questo file rappresenta un'origine dati di esempio per l'app. Il file data.js include dati statici che di solito devono essere sostituiti con dati dinamici. Se ad esempio l'app effettua una singola richiesta xhr per ottenere dati RSS o JSON, devi in genere includere questo codice in data.js. In questo modo potrai usare facilmente i tuoi dati senza cambiare il modello di dati presente nei modelli.
Suggerimento I modelli Hub/Pivot, Hub e Pivot recuperano anche dati statici dai file resjson che supportano la globalizzazione. Per altre info, vedi Esempio di binding dei dati all'interfaccia utente nei modelli Hub/Pivot, Hub e Pivot.
Quando aggiungi dati personali a un'app, devi fare attenzione ad alcuni aspetti:
- Gruppi ed elementi sono collegati in modo intrinseco. L'app prevede che i dati degli elementi siano organizzati in gruppi. Puoi scollegare le due entità nella tua implementazione, ma affinché l'implementazione funzioni devi modificare il codice. In questo argomento viene illustrato l'utilizzo dei gruppi nel modello di dati.
- Quando implementi dati personalizzati per un'app in data.js, devi accertarti che i nomi di proprietà inerenti ai dati personalizzati siano mappati ai nomi di proprietà usati dal modello. Puoi modificare i nomi usati dal modello, ma questa operazione richiede un'altra revisione del codice. In questo argomento troverai alcuni esempi di come fare.
Elementi e gruppi
I dati dei modelli sono archiviati in un elemento WinJS.Binding.List. Questo codice mostra la dichiarazione di un elenco nel file data.js.
var list = new WinJS.Binding.List();
Una matrice di dati degli elementi (in questo esempio sampleItems
) viene passata a WinJS.Binding.List dalla funzione push, in questo modo:
generateSampleData.forEach(function (item) {
list.push(item);
});
WinJS.Binding.List include la logica interna per la gestione dei raggruppamenti di dati. La matrice sampleItems
include una proprietà group
che identifica il gruppo a cui appartiene l'elemento (nei dati di esempio i gruppi sono specificati nella matrice sampleGroups
). Ecco la matrice di dati nella funzione generateSampleData
:
function generateSampleData() {
// . . .
var sampleGroups = [
{ key: "group1", title: "Group Title: 1", // . . .
// . . .
];
var sampleItems = [
{ group: sampleGroups[0], title: "Item Title: 1", // . . .
// . . .
];
return sampleItems;
}
Quando modifichi l'app per i dati personalizzati, puoi seguire lo stesso schema per il raggruppamento dei dati. Per set di dati più piccoli, è consigliabile usare WinJS.Binding.List per ListView. Se non raggruppi gli elementi, puoi comunque usare WinJS.Binding.List, ma devi modificare il codice del modello nei punti in cui il modello prevede di trovare dati basati sui gruppi.
Suggerimento WinJS.Binding.List è un'origine dati sincrona che usa una matrice JavaScript. Per set di dati molto grandi, ad esempio con migliaia di elementi, può essere necessario usare un'origine dati asincrona. Per ulteriori informazioni, vedi Uso ListView.
La funzione createGrouped di WinJS.Binding.List specifica come raggruppare gli elementi usando una chiave di gruppo e un valore del gruppo di elementi. Questa funzione viene chiamata in data.js. key
e group
sono entrambi nomi di proprietà specificati nelle matrici di dati di esempio.
var groupedItems = list.createGrouped(
function groupKeySelector(item) { return item.group.key; },
function groupDataSelector(item) { return item.group; }
);
Quando l'app del modello necessita di un elenco di elementi, chiama getItemsFromGroup
, che restituisce un elemento WinJS.Binding.List contenente solo gli elementi che appartengono al gruppo specificato.
function getItemsFromGroup(group) {
return list.createFiltered(function (item) {
return item.group.key === group.key;
});
}
Suggerimento Funzioni come getItemsFromGroup
, che chiamano createFiltered, creano un nuovo progetto di WinJS.Binding.List e potrebbe essere necessario eliminare l'oggetto restituito se esci dalla pagina. Per eliminare l'oggetto, chiama il metodo WinJS.Binding.List.dispose.
La funzione define della Libreria di Windows per JavaScript espone i dati per l'uso nell'app specificando uno spazio dei nomi denominato Data
insieme a un set di funzioni membro pubblico.
WinJS.Namespace.define("Data", {
items: groupedItems,
groups: groupedItems.groups,
getItemReference: getItemReference,
getItemsFromGroup: getItemsFromGroup,
resolveGroupReference: resolveGroupReference,
resolveItemReference: resolveItemReference
});
Se vuoi definire un'origine dati diversa per ogni pagina dell'app, oppure un modello di dati diverso, dovrai sostituire tutte le chiamate a questi membri nel codice JavaScript.
Associazione di dati di elementi e gruppi all'interfaccia utente
Il codice seguente mostra un esempio di markup per il controllo ListView. L'origine dati per ListView è specificata nella proprietà itemDataSource, illustrata qui. L'esempio proviene da split.html nel modello Split.
<div class="itemlist win-selectionstylefilled" aria-label="List of this group's items" data-win-control="WinJS.UI.ListView" data-win-options="{
layout: {type: WinJS.UI.ListLayout},
currentItem: {type: WinJS.UI.ObjectType.item, index: 0, hasFocus: true},
selectionMode: 'single',
swipeBehavior: 'none',
tapBehavior: 'toggleSelect',
itemDataSource: select('.pagecontrol').winControl.itemDataSource,
itemTemplate: select('.itemtemplate'),
onselectionchanged: select('.pagecontrol').winControl.selectionChanged
}">
</div>
Nel codice precedete, una proprietà itemDataSource
associata alla pagina è stata assegnata alla proprietà itemDataSource del controllo ListView.
Nei modelli i dati sono in genere associati all'interfaccia utente nella funzione init o nella funzione ready, definita nel file con estensione js associato a ogni pagina HTML. Il codice seguente è contenuto nella funzione init per split.html. In questo codice l'app ottiene un riferimento a un gruppo e quindi chiama getItemsFromGroup
, implementato in data.js. Come abbiamo detto in precedenza, getItemsFromGroup
restituisce un elemento WinJS.Binding.List che contiene solo gli elementi inclusi nel gruppo specificato.
this._group = Data.resolveGroupReference(options.groupKey);
this._items = Data.getItemsFromGroup(this._group);
Associamo quindi l'elenco restituito da getItemsFromGroup alla proprietà itemDataSource
della pagina, che associa i dati a ListView, e specifichiamo inoltre il gestore per la selezione di elementi (_selectionChanged
).
this.itemDataSource = this._items.dataSource;
this.selectionChanged = ui.eventHandler(this._selectionChanged.bind(this));
Per visualizzare ogni elemento in ListView, l'app associa un modello a ListView, come illustrato qui. Il codice viene visualizzato nel markup per il controllo ListView e usa la proprietà itemTemplate per specificare un elemento DIV con nome di classe itemtemplate
.
itemTemplate: select('.itemtemplate')
I modelli WinJS, basati su WinJS.Binding.Template, vengono usati per formattare e visualizzare istanze multiple di dati. Il modello più comune usato nei modelli Grid e Split è il modello di elemento usato per visualizzare gli elementi in ListView. Come ogni oggetto modello WinJS, per dichiararlo devi aggiungere un attributo data-win-control e impostare l'attributo su WinJS.Binding.Template. Ecco il codice HTML per itemtemplate
in split.html:
<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
<div class="item">
<img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" />
<div class="item-info">
<h3 class="item-title win-type-ellipsis"
data-win-bind="textContent: title"></h3>
<h6 class="item-subtitle win-type-ellipsis"
data-win-bind="textContent: author"></h6>
</div>
</div>
</div>
L'elemento itemtemplate
viene usato per elementi ListView arbitrari. Gli elementi ListView possono essere gruppi o singoli elementi di dati, a seconda del contesto. In items.html, ad esempio, gli elementi ListView sono gruppi.
Importante I modelli creati usando WinJS.Binding.Template non sono correlati a modelli di elemento e di progetto di Visual Studio, come Applicazione griglia e Applicazione divisa.
I modelli di progetto prevedono la presenza di determinate proprietà nei dati e queste proprietà sono denominate in modo esplicito nel codice HTML. Nel codice HTML precedente per itemtemplate
puoi trovare proprietà come title
e subtitle
. Se i dati personalizzati della tua app non usano questi nomi di proprietà, dovrai eseguire una delle operazioni seguenti:
- Mappare i dati a questi nomi di proprietà (in genere in data.js), oppure
- Correggere tutti i riferimenti di codice HTML e con estensione js impostando queste proprietà nel codice del modello, in modo che corrispondano ai nomi di proprietà usati nei dati. Le proprietà usate nei modelli includono:
title
,subtitle
,description
ebackgroundImage
(proprietà di gruppi ed elementi)group
econtent
(proprietà di elementi)key
(proprietà di gruppi)
In base allo stesso schema del modello WinJS, anche il modello Applicazione griglia usa un elemento headerTemplate
in alcune pagine HTML.
Esempio di binding dei dati all'interfaccia utente nei modelli Hub/Pivot, Hub e Pivot
In Visual Studio i modelli di progetto Hub/Pivot, Hub e Pivot dimostrano come implementare due diverse origini dati:
- Dati statici globalizzati archiviati nei file di risorse resjson. Questi dati vengono usati in alcuni controlli delle sezioni dell'app (PivotItem o HubSection).
- Dati di esempio in data.js, che rappresentano il modello di dati. Questo file è lo stesso dei modelli Grid e Split. I dati di esempio vengono usati nel controllo ListView in una delle sezioni dell'app.
Le funzioni dichiarative nel codice HTML vengono usate per ottenere inizialmente i dati di esempio. Il modello di dati è sincrono per impostazione predefinita. Per personalizzare i modelli in modo che usino dati dinamici in tutte le sezioni, è necessario apportare alcune modifiche ai file hub.html, hub.js e ad altri file. Le app di esempio seguenti mostrano come personalizzare i modelli Hub/Pivot e Hub per supportare i dati asincroni:
Poiché i dati globalizzati nel file resjson sono facilmente sostituibili, le app di esempio lasciano questo file di risorse invariato. Nelle app di esempio i dati per gli elementi <img> e il controllo ListView presenti nelle sezioni di Hub/Pivot vengono recuperati in modo asincrono.
Per altre informazioni su come fornire dati globalizzati nei file resjson, vedi Guida introduttiva: Traduzione delle risorse dell'interfaccia utente
Per supportare il binding di dati asincroni al controllo ListView di Hub/Pivot, sostituisci innanzitutto in hub.js queste variabili globali che chiamano il modello di dati:
var section3Group = Data.resolveGroupReference("group4");
var section3Items = Data.getItemsFromGroup(section3Group);
con queste dichiarazioni variabili:
var section3Group = "group2";
var section3Items;
Devi inoltre modificare l'implementazione delle funzioni dichiarative in hub.js. Nell'implementazione predefinita del modello queste funzioni dipendono dai dati già disponibili (ad esempio la chiamata a section3Items.dataSource
). Sostituisci questo codice:
section3DataSource: section3Items.dataSource,
section3HeaderNavigate: util.markSupportedForProcessing(function (args) {
nav.navigate("/pages/section/section.html", { title: args.detail.section.header,
groupKey: section3Group.key });
}),
section3ItemNavigate: util.markSupportedForProcessing(function (args) {
var item = Data.getItemReference(section3Items.getAt(args.detail.itemIndex));
nav.navigate("/pages/item/item.html", { item: item });
}),
con questo:
section3DataSource: null,
section3HeaderNavigate: util.markSupportedForProcessing(function (args) {
nav.navigate("/pages/section/section.html", { title: args.detail.section.header,
groupKey: section3Group });
}),
section3ItemNavigate: util.markSupportedForProcessing(function (args) {
var itemSet = section3Items;
var itemObj = itemSet.getAt(args.detail.itemIndex);
var item = [itemObj.group.key, itemObj.title, itemObj.backgroundImage];
nav.navigate("/pages/item/item.html", { item: item });
}),
Questo codice imposta la funzione section3DataSource
su Null, per evitare che venga eseguito un tentativo di binding dei dati prima che questi siano pronti. Successivamente imposteremo l'origine dati in una funzione di data binding (_bindData
o bindListView
, in base all'app di esempio).
La funzione di data binding viene chiamata quando i dati sono disponibili. Per consentire questa operazione, aggiungiamo un listener per l'evento del modello di dati dataReady
, definito nell'app di esempio in data.js.
this._observer = Data.getObservable();
this._observer.addEventListener('dataReady', this.onDataCompleted.bind(this));
L'app chiama la funzione di data binding dal gestore eventi onDataCompleted
(non illustrato). Il codice per la funzione _bindData
dell'esempio di modello Hub è illustrato qui. In questo codice impostiamo la proprietà itemDataSource di ListView.
_bindData: function (context, grp1Items, grp2Items) {
var self = context;
// . . .
self._items = grp2Items;
section3Items = self._items;
self._section3lv.itemDataSource = self._items.dataSource;
// . . .
},
Se per passare alla pagina viene usato il pulsante Indietro, la funzione di data binding viene chiamata direttamente dalla funzione di inizializzazione della pagina, perché non è necessario attendere nuovi dati.
Suggerimento Nel codice del modello Hub, per eseguire una query sul modello DOM per l'elemento ListView (archiviato in _section3lv
), l'app chiama una funzione _hubReady
dal gestore dell'evento loadingstatechanged
del controllo Hub. Questo evento si attiva solo dopo che il caricamento della pagina hub è stato completato. Usando questo gestore eventi possiamo fare una query sul modello DOM per ottenere l'elemento DIV annidato associato a ListView.
Il codice completo per fare in modo che i dati asincroni funzionino nei modelli Hub/Pivot e Hub è disponibile nel lettore Web JSON che usa il modello Hub/Pivot e nel lettore Web JSON che usa il modello Hub. Oltre alle personalizzazioni illustrate qui, abbiamo apportato le modifiche seguenti all'app di esempio:
- Inserimento di codice nel modello di dati (data.js) per il recupero dei dati tramite una richiesta xhr e l'analisi dei dati JSON (da Flickr).
- Inserimento di codice nel modello di dati per la gestione di richieste di dati multiple e l'attivazione dell'evento
dataReady
quando i dati vengono restituiti. - Inserimento di una casella di input nell'interfaccia utente per la richiesta di nuovi dati.
- Inserimento di una barra di stato per mostrare lo stato della richiesta di dati.
- Aggiunta di stile CSS per la casella di input e la barra di stato.
- Inserimento di funzioni per l'inizializzazione della pagina dopo il caricamento completo del controllo Hub, ad esempio
_hubReady
o_hubReadyPhone
. - Modifica degli elementi <img> di Hub/Pivot o Hub per il supporto degli eventi clic (i file modificati sono specifici del modello).
- Modifica dei file per il binding dei dati asincroni agli elementi <img> di Hub/Pivot o Hub (i file modificati sono specifici del modello).
- Modifica di hub.js per il supporto del passaggio alle immagini dagli elementi <img> di Hub (i file modificati sono specifici del modello).
- Modifica di item.html e item.js per il supporto della visualizzazione di immagini singole.
Esempio di associazione dei dati all'interfaccia utente (Grid e Split)
Questa sezione mostra come implementare un'origine dati personalizzata nei modelli di progetto Grid e Split. Il codice di esempio usa una richiesta xhr per generare dati RSS.
Importante Per l'implementazione di dati asincroni nel modello Hub, vedi Binding dei dati con l'interfaccia utente nel modello Hub.
Aggiornamento di data.js
Creare un nuovo progetto in Visual Studio. Usa il modello di progetto Applicazione divisa o Applicazione griglia.
In data.js aggiungi le variabili seguenti quasi all'inizio del file, dopo l'istruzione
use strict
:var lightGray = "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY7h4+cp/AAhpA3h+ANDKAAAAAElFTkSuQmCC"; var mediumGray = "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY5g8dcZ/AAY/AsAlWFQ+AAAAAElFTkSuQmCC";
In data.js rimuovi la funzione
generateSampleData
contenente le matricisampleGroups
esampleItems
.Sostituiremo questi dati con i dati RSS. Non useremo la maggior parte delle variabili segnaposto, come
groupDescription
, ma per garantire il funzionamento del nuovo codice riutilizzeremo le immagini segnapostolightGray
emediumGray
.Nella stessa posizione da cui hai rimosso
generateSampleData
, aggiungi il codice seguente a data.js:function getFeeds() { // Create an object for each feed. blogs = [ { key: "blog1", url: 'https://windowsteamblog.com/windows/b/developers/atom.aspx', title: 'tbd', subtitle: 'subtitle', updated: 'tbd', backgroundImage: lightGray, acquireSyndication: acquireSyndication, dataPromise: null }, { key: "blog2", url: 'https://windowsteamblog.com/windows/b/windowsexperience/atom.aspx', title: 'tbd', subtitle: 'subtitle', updated: 'tbd', backgroundImage: lightGray, acquireSyndication: acquireSyndication, dataPromise: null }] // Get the content for each feed in the blog's array. blogs.forEach(function (feed) { feed.dataPromise = feed.acquireSyndication(feed.url); dataPromises.push(feed.dataPromise); }); // Return when all asynchronous operations are complete return WinJS.Promise.join(dataPromises).then(function () { return blogs; }); }; function acquireSyndication(url) { return WinJS.xhr( { url: url, headers: { "If-Modified-Since": "Mon, 27 Mar 1972 00:00:00 GMT" } }); } function getBlogPosts() { getFeeds().then(function () { // Process each blog. blogs.forEach(function (feed) { feed.dataPromise.then(function (articlesResponse) { var articleSyndication = articlesResponse.responseXML; // Get the blog title and last updated date. if (articleSyndication) { // Get the blog title and last updated date. feed.title = articleSyndication.querySelector( "feed > title").textContent; var ds = articleSyndication.querySelector( "feed > updated").textContent; var date = ds.substring(5, 7) + "-" + ds.substring(8, 10) + "-" + ds.substring(0, 4); feed.updated = "Last updated " + date; // Process the blog posts. getItemsFromXml(articleSyndication, blogPosts, feed); } else { // There was an error loading the blog. feed.title = "Error loading blog"; feed.updated = "Error"; blogPosts.push({ group: feed, key: "Error loading blog", title: feed.url, author: "Unknown", month: "?", day: "?", year: "?", content: "Unable to load the blog at " + feed.url }); } }); }); }); return blogPosts; } function getItemsFromXml(articleSyndication, blogPosts, feed) { var posts = articleSyndication.querySelectorAll("entry"); // Process each blog post. for (var postIndex = 0; postIndex < posts.length; postIndex++) { var post = posts[postIndex]; // Get the title, author, and date published. var postTitle = post.querySelector("title").textContent; var postAuthor = post.querySelector("author > name").textContent; var pds = post.querySelector("published").textContent; var postDate = pds.substring(5, 7) + "-" + pds.substring(8, 10) + "-" + pds.substring(0, 4); // Process the content so that it displays nicely. var staticContent = toStaticHTML(post.querySelector( "content").textContent); // Store the post info we care about in the array. blogPosts.push({ group: feed, key: feed.title, title: postTitle, author: postAuthor, pubDate: postDate, backgroundImage: mediumGray, content: staticContent }); } }
In data.js sostituisci questo codice:
var list = new WinJS.Binding.List(); var groupedItems = list.createGrouped( function groupKeySelector(item) { return item.group.key; }, function groupDataSelector(item) { return item.group; } ); // TODO: Replace the data with your real data. // You can add data from asynchronous sources whenever it becomes available. generateSampleData.forEach(function (item) { list.push(item); });
con questo:
var dataPromises = []; var blogs; var blogPosts = new WinJS.Binding.List(); var list = getBlogPosts(); var groupedItems = list.createGrouped( function groupKeySelector(item) { return item.group.key; }, function groupDataSelector(item) { return item.group; } );
Useremo di nuovo il codice in createGrouped che specifica il raggruppamento— delle funzioni groupKeySelector e groupDataSelector.
Dato che abbiamo modificato alcuni dei nomi di proprietà previsti dal modello, dovremo apportare alcuni aggiornamenti nelle pagine HTML. In particolare, per tutte le proprietà
subtitle
che fanno riferimento a un elemento (non a un gruppo), dobbiamo modificaresubtitle
inauthor
. Per le proprietàdescription
che fanno riferimento a un elemento, dobbiamo modificaredescription
inpubDate
.Per implementare queste modifiche nell'interfaccia utente, vedi una delle sezioni seguenti:
- Associazione di dati di esempio all'interfaccia utente nel modello Split
- Associazione di dati di esempio all'interfaccia utente nel modello Grid
Associazione di dati di esempio all'interfaccia utente nel modello Split
Per usare il codice di esempio nel modello Applicazione divisa, apri split.html.
In split.html dobbiamo modificare alcune righe nell'elemento DIV con un nome di classe
itemtemplate
. Modifica questa riga:<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6>
in queste:
<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: author"></h6>
Inoltre in split.html la sezione relativa all'articolo (
articlesection
) include informazioni di intestazione che devono essere aggiornate. Modifica questa riga:<h4 class="article-subtitle" data-win-bind="textContent: subtitle"></h4>
in queste:
<h4 class="article-subtitle" data-win-bind="textContent: author"></h4>
Apri items.html.
Il modello di elemento WinJS definito nel codice HTML contiene elementi ListView arbitrari. In items.html il modello è usato per mostrare i gruppi (blog). L'unica proprietà di gruppo che dobbiamo modificare qui è
subtitle
.<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6>
Modifica la proprietà
subtitle
inupdated
, come illustrato qui:<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: updated"></h6>
Salva il progetto e premi F5 per eseguire il debug dell'app.
Vedrai immediatamente il titolo della pagina, ma noterai un breve ritardo mentre vengono recuperati i dati del feed. Quando tutto sarà a posto, vedrai ogni blog nella home page. Fai clic su uno dei blog per vedere i post nella visualizzazione master/dettaglio.
Associazione di dati di esempio all'interfaccia utente nel modello Grid
Prima di eseguire questi passaggi, aggiorna il file di progetto data.js come descritto in Esempio di associazione dei dati all'interfaccia utente.
Per usare il codice RSS di esempio nel modello Applicazione griglia, apri groupDetail.html.
Questa pagina mostra un singolo gruppo (un blog) e gli elementi (post di blog) che fanno parte del gruppo.
In groupDetail.html dobbiamo modificare alcune righe nell'elemento DIV con un nome di classe
item-info
. Modifica queste righe:<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6> <h4 class="item-description" data-win-bind="textContent: description"></h4>
in queste:
<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: author"></h6> <h4 class="item-description" data-win-bind="textContent: pubDate"></h4>
In groupDetail.html il modello di intestazione descrive informazioni di gruppo, non singoli elementi. Non dobbiamo quindi modificare la proprietà
subtitle
. Ecco il modello di intestazione:<div class="headertemplate" data-win-control="WinJS.Binding.Template"> <h2 class="group-subtitle" data-win-bind="textContent: subtitle"></h2> <img class="group-image" src="#" data-win-bind="src: backgroundImage; alt: title" /> <h4 class="group-description" data-win-bind="innerHTML: description"></h4> </div>
Non disponiamo tuttavia di una proprietà
description
per ogni gruppo (ma solo per gli elementi) e quindi dobbiamo modificare la proprietà inupdated
nel codice precedente, come mostrato qui.<h4 class="group-description" data-win-bind="innerHTML: updated"></h4>
Apri groupedItems.html, che mostra tutti i gruppi e i singoli post di blog che contengono.
In questa pagina il modello di elemento generico WinJS visualizza singoli elementi (post di blog) e quindi dobbiamo aggiornare la proprietà
subtitle
. Modifica queste righe:<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6>
in queste:
<h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: author"></h6>
Salva il progetto e premi F5 per eseguire il debug dell'app.
Vedrai immediatamente il titolo della pagina, ma noterai un breve ritardo mentre vengono recuperati i dati del feed. Quando i dati vengono restituiti, come previsto, vedrai gli elementi in ogni blog nella home page. Fai clic su un'intestazione di gruppo per visualizzare la pagina del gruppo, oppure su un elemento per visualizzare un singolo post di blog.
Elenco del codice per data.js
Qui è riportato l'elenco del codice completo per data.js. Per entrambi gli esempi dei modelli Applicazione griglia e Applicazione divisa mostrati in precedenza, viene usato lo stesso file data.js. Per visualizzare il file data.js del modello Hub/Pivot, vedi Lettore Web JSON che usa il modello Hub/Pivot. Per visualizzare il file data.js del modello Hub, vedi Lettore Web JSON che usa il modello Hub.
(function () {
"use strict";
var lightGray = "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY7h4+cp/AAhpA3h+ANDKAAAAAElFTkSuQmCC";
var mediumGray = "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY5g8dcZ/AAY/AsAlWFQ+AAAAAElFTkSuQmCC";
var dataPromises = [];
var blogs;
var blogPosts = new WinJS.Binding.List();
var list = getBlogPosts();
var groupedItems = list.createGrouped(
function groupKeySelector(item) { return item.group.key; },
function groupDataSelector(item) { return item.group; }
);
WinJS.Namespace.define("Data", {
items: groupedItems,
groups: groupedItems.groups,
getItemReference: getItemReference,
getItemsFromGroup: getItemsFromGroup,
resolveGroupReference: resolveGroupReference,
resolveItemReference: resolveItemReference
});
// Get a reference for an item, using the group key and item title as a
// unique reference to the item that can be easily serialized.
function getItemReference(item) {
return [item.group.key, item.title];
}
// This function returns a WinJS.Binding.List containing only the items
// that belong to the provided group.
function getItemsFromGroup(group) {
return list.createFiltered(function (item) { return item.group.key === group.key; });
}
// Get the unique group corresponding to the provided group key.
function resolveGroupReference(key) {
return groupedItems.groups.getItemFromKey(key).data;
}
// Get a unique item from the provided string array, which should contain a
// group key and an item title.
function resolveItemReference(reference) {
for (var i = 0; i < groupedItems.length; i++) {
var item = groupedItems.getAt(i);
if (item.group.key === reference[0] && item.title === reference[1]) {
return item;
}
}
}
function getFeeds() {
// Create an object for each feed.
blogs = [
{
key: "blog1", url:
'https://windowsteamblog.com/windows/b/developers/atom.aspx',
title: 'tbd', subtitle: 'subtitle', updated: 'tbd',
backgroundImage: lightGray,
acquireSyndication: acquireSyndication, dataPromise: null
},
{
key: "blog2", url:
'https://windowsteamblog.com/windows/b/windowsexperience/atom.aspx',
title: 'tbd', subtitle: 'subtitle', updated: 'tbd',
backgroundImage: lightGray,
acquireSyndication: acquireSyndication, dataPromise: null
}]
// Get the content for each feed in the blog's array.
blogs.forEach(function (feed) {
feed.dataPromise = feed.acquireSyndication(feed.url);
dataPromises.push(feed.dataPromise);
});
// Return when all asynchronous operations are complete
return WinJS.Promise.join(dataPromises).then(function () {
return blogs;
});
};
function acquireSyndication(url) {
return WinJS.xhr({
url: url,
headers: { "If-Modified-Since": "Mon, 27 Mar 1972 00:00:00 GMT" }
});
}
function getBlogPosts() {
getFeeds().then(function () {
// Process each blog.
blogs.forEach(function (feed) {
feed.dataPromise.then(function (articlesResponse) {
var articleSyndication = articlesResponse.responseXML;
if (articleSyndication) {
// Get the blog title and last updated date.
feed.title = articleSyndication.querySelector(
"feed > title").textContent;
var ds = articleSyndication.querySelector(
"feed > updated").textContent;
var date = ds.substring(5, 7) + "-" +
ds.substring(8, 10) + "-" + ds.substring(0, 4);
feed.updated = "Last updated " + date;
// Process the blog posts.
getItemsFromXml(articleSyndication, blogPosts, feed);
}
else {
// There was an error loading the blog.
feed.title = "Error loading blog";
feed.updated = "Error";
blogPosts.push({
group: feed,
key: "Error loading blog",
title: feed.url,
author: "Unknown",
month: "?",
day: "?",
year: "?",
content: "Unable to load the blog at " + feed.url
});
}
});
});
});
return blogPosts;
}
function getItemsFromXml(articleSyndication, blogPosts, feed) {
var posts = articleSyndication.querySelectorAll("entry");
// Process each blog post.
for (var postIndex = 0; postIndex < posts.length; postIndex++) {
var post = posts[postIndex];
// Get the title, author, and date published.
var postTitle = post.querySelector("title").textContent;
var postAuthor = post.querySelector("author > name").textContent;
var pds = post.querySelector("published").textContent;
var postDate = pds.substring(5, 7) + "-" + pds.substring(8, 10)
+ "-" + pds.substring(0, 4);
// Process the content so that it displays nicely.
var staticContent = toStaticHTML(post.querySelector(
"content").textContent);
// Store the post info we care about in the array.
blogPosts.push({
group: feed, key: feed.title, title: postTitle,
author: postAuthor, pubDate: postDate,
backgroundImage: mediumGray, content: staticContent
});
}
}
})();
Argomenti correlati
Modelli di progetto JavaScript