Windows Metro – Clouder! (3) – Afficher une liste de titre depuis SoundCloud

Dans le tutorial précédent, on a vu comment réaliser un appel XHR en JavaScript depuis notre application Windows 8. Maintenant, on va afficher les résultats sous forme de liste avec le composant ListView fournit par WinJS.

Ajouter le composant ListView

Microsoft fournit de nombreux composants pour vous aider à respecter les UX guidelines des applications Metro sans trop forcer. Parmi eux, le composant ListView permettant d’afficher des listes d’éléments. J’ai déjà fait un tutorial sur ce composant que je vous invite à consulter:

Windows Metro – Afficher une liste simple avec le composant WinJS.UI.ListView

Ouvrez donc /pages/home/home.html et ajouter ceci dans le tag <section>:

<section aria-label="Main content" role="main">
  <div class="tracklist" data-win-control="WinJS.UI.ListView" />
</section>

Création d’un objet WinJS.Binding.List à partir du résultat de la requête XHR

A partir des résultats de notre requête XHR, on va donc venir peupler notre ListView. Pour cela, on va créer un objet WinJS.Bindable.List qui une sorte de « Array amélioré », un ArrayCollection pour les Flexers. Dans cette List, on va venir mettre toutes nos tracks:

(function () {
    "use strict";

    WinJS.UI.Pages.define("/pages/home/home.html", {
        // This function is called whenever a user navigates to this page. It
        // populates the page elements with the app's data.
        ready: function (element, options) {
            WinJS.xhr({ url: "https://api.soundcloud.com/tracks.json?client_id=2e601fddcc4a07954c3da7077f81a1e1" }).done(
            function fulfilled(result) {
                if (result.status === 200) {
                    var list = new WinJS.Binding.List();
                    var data = JSON.parse(result.responseText);
                    for (var i = 0, l = data.length; i < l; i++) {
                        var track = data[i];
                        list.push(track);
                    }

                }
            });
        }
    });
})();

Notez que l’on pourrait simplement passer le tableau de « tracks » directement dans le constructeur de WinJS.Binding.List:

var data = JSON.parse(result.responseText);
var list = new WinJS.Binding.List(data);

Même résultat mais on aura besoin plus tard de boucler sur nos résultat pour leur affecter un pré-traitement.

Lier la ListView à la variable List

On va maintenant lier les 2 en liant la propriété « itemDataSource » de notre composant List (qui peut être accédé par sa propriété « winControl ») à la propriété « dataSource » de notre objet List. En effet, on ne passe pas directement l’objet de type WinJS.Binding.List mais sa propriété « dataSource ».

Pour cela, on va utiliser la fonction utilitaire WinJS.UI.setOptions(<composant>, {options}) et au passage, on va donner le « layout » de notre liste:

...	list.push(track);
}
var listView = document.querySelector(".tracklist");
WinJS.UI.setOptions(listView.winControl, {
	layout: new WinJS.UI.ListLayout(),
	itemDataSource: list.dataSource
});

Lancez votre application et vous obtenez:

Votre donnée apparaît en brut dans la liste. Si vous avez suivi le tutorial sur ListView cité en début d’article, vous savez qu’il manque encore une étape, il faut assigner un template (itemRenderer pour les Flexers) qui va indiquer à IE10 comment faire le rendu de chaque élément.

Assigner un template à la ListView

On va créer un template sympa pour chaque résultat qui affiche la pochette en fond (dont l’url se trouve dans « artwork_url » dans le flux JSON), le titre, l’artiste et le style. Ce template va être réutilisé dans de nombreuses listes dans notre application, y compris dans des listes qui ne sont pas dans la page home.html. Pour éviter de répéter du code, on va donc placer notre template dans la page default.html.

Voici un exemple de template de base:

<body>
    <!-- TRACK TEMPLATE -->
     <div class="trackTemplate" data-win-control="WinJS.Binding.Template">
        <img class="item-image" src="#" data-win-bind="src: artwork_url; alt: title" />
        <div class="item-overlay">
            <h4 class="item-title" data-win-bind="textContent: title"></h4>
            <h6 class="item-subtitle win-type-ellipsis" data-win-bind="textContent: subtitle"></h6>
        </div>
    </div>
    <div id="contenthost" data-win-control="Application.PageControlNavigator" data-win-options="{home: '/pages/home/home.html'}"></div>

On a donné à notre template un nom de class « trackTemplate ». C’est par ce className que l’on va indiquer à notre ListView quel template utiliser. Rendez-vous donc dans /pages/home/home.html et assignez le template dans les options du composant:

<div class="tracklist" data-win-control="WinJS.UI.ListView" data-win-options="{itemTemplate: select('.trackTemplate')}"/>

Relancez votre application:

Ça commence à prendre de l’allure mais on a deux problèmes. Le premier est que le défilement est vertical (alors que les applications Metro ont plutôt du scroll horizontal) et le deuxième est que tout se chevauche.

On va résoudre notre premier problème en modifiant le layout de notre composant et en passant en « WinJS.UI.GridLayout » au lieu de « WinJS.UI.ListLayout »:

 WinJS.UI.setOptions(listView.winControl, {
                        layout: new WinJS.UI.GridLayout(),
                        itemDataSource: list.dataSource
                    });

ce qui donne:

Maintenant, il faut donner un peu de style à chaque élément, pour lui fixer une taille, gérer les overlap, transparence etc. Cela se passe en CSS, dans le fichier /css/default.css commun à toutes les pages (car dans la page default.html):

.tracklist .win-horizontal.win-viewport .win-surface {
    margin-left: 45px;
    margin-bottom: 60px;
}
.tracklist {
    height: 100%;
    position: relative;
    width: 100%;
    z-index: 0;
}

.tracklist .win-item {
    -ms-grid-columns: 1fr;
    -ms-grid-rows: 1fr 70px;
    display: -ms-grid;
    height: 250px;
    width: 250px;
}

.tracklist .win-item .item-image {
    -ms-grid-row-span: 2;
}

.tracklist .win-item .item-overlay {
    -ms-grid-row: 2;
    -ms-grid-rows: 1fr 21px;
    display: -ms-grid;
    padding: 6px 15px 2px 15px;
}

.tracklist .win-item .item-overlay .item-title {
    -ms-grid-row: 1;
    overflow: hidden;
    width: 220px;
}

.tracklist .win-item .item-overlay .item-subtitle {
    -ms-grid-row: 2;
    width: 220px;
}

La classe « win-item » est utilisée par Windows Metro à chaque fois qu’un template est rendu à l’écran, on va donc styler chaque item avec une règle de type « .tracklist .win-item ». Voilà le résultat:

C’est mieux mais cela reste assez moche. On note au passage que l’on fait un Binding (liaison dynamique) sur la propriété « subtitle » qui n’existe pas sur notre objet « Track ». On peut voir aussi que de nombreuses jaquettes ne sont pas renseignées et l’on se retrouve avec des images non-définies. En effet, ici on liste les dernières tracks de SoundCloud et l’upload d’une photo (ou par les metadata du morceau) n’est pas obligatoire. Un cas que l’on va devoir prendre en compte par la suite.

Conclusion

Fin de la 3ème étape et on laisse notre application dans un état pas terrible. Dans le prochain tutorial, on va s’occuper de faire un pré-traitement sur les objets venant de SoundCloud et donner un peu de style à notre application avec Microsoft Blend.

2 réflexions au sujet de « Windows Metro – Clouder! (3) – Afficher une liste de titre depuis SoundCloud »

  1. Ping : Windows Metro – Clouder! (4) – Donner du style avec Microsoft Blend | HTML5 Tutorial

  2. palife

    Bonjour.j’ai renoncé à faire un protocole d’authentification. je me suis retourné vers vers un appel xhr d’un fichier xml. Mon fichier et le suivant http://musics4.me/flux-rss.xml.
    Mon probléme ce situe au niveau de ses ligne:function fulfilled(result) {
    if (result.status === 200) {
    var list = new WinJS.Binding.List();
    var data = JSON.parse(result.responseText);
    for (var i = 0, l = data.length; i < l; i++) {
    var track = data[i];
    list.push(track);
    Je ne vois pas par quoi les remplacer pour remplir mon listview. Pourriez vous m'aider, merci

    Répondre

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *