Le Post Infeeny

Les articles des consultants et experts Infeeny

Gérer le layout d’une WinJS.UI.ListView de facon déclarative

Gérer les états visuels dans les applications Windows 8 en html / javascript est vraiment intuitif grâce aux media-queries. D’applications en applications il reste cependant un aspect pénible lorsqu’on attaque la gestion du snap et les changements d’orientation : la ListView.
Avec Windows 8.1 ce contrôle permet maintenant (enfin) de faire des grilles horizontales ou verticales, ou de gérer l’affichage en listes.
Bien souvent on passe d’un mode de layout à l’autre selon l’orientation et/ou la résolution, et c’est une des rares chose qu’on est amené à faire en code plutôt qu’avec les media-queries. Avec Windows 8.1 et son mode snap vitaminé, on doit parfois contrôler la résolution et plus seulement les états visuels, donc encore plus de code à faire (et pas du genre passionnant).

Il serait tellement plus agréable de pouvoir déclarer des media-queries et leur associer le layout de la ListView…

Mais attendez… pourquoi on ne pourrait pas faire ca ? les media-queries peuvent être manipulées très facilement en javascript :

var mq = window.matchMedia("(orientation : portrait) and (max-width: 400px)");
if (mq.matches){
    //la media-querie est ok
}

Pas mal n’est ce pas ? il y a encore mieux, on peut déclarer une media-querie et souscrire à un abonnement qui va se déclencher lorsque celle-ci sera évaluée !

var mq = window.matchMedia("(orientation : portrait) and (max-width: 400px)");
mq.addListener(function(mq){
    if (mq.matches){
        //la media-querie est ok
    }
});

Vous voyez où je veux en venir ? il suffit de wrapper ça dans un joli contrôle WinJS et de le faire pointer sur la liste. Quelques lignes de code plus tard, on a quelque chose comme ca dans la page html :

<div id="mylistview" data-win-control="WinJS.UI.ListView" data-win-options="{
    itemTemplate: select('#listitemtemplate'),
    itemDataSource: DummyDataSource
}"></div>

<div id="listlayout" data-win-control="MCNEXT.UI.SmartListLayout" data-win-options="{
    listView: select('#mylistview'),
    layouts:{
        default : { query: '(orientation: landscape)'}, layout : WinJS.UI.GridLayout
        vert : { query: '(orientation: portrait) and (min-width: 350px)', layout : WinJS.UI.GridLayout, options: { orientation : 'vertical'}},
        snap : { query: '(orientation: portrait) and (max-width: 350px)', layout : WinJS.UI.ListLayout },
    }
}"></div>

Pour le voir de vos propres yeux, vous pouvez télécharger une appli de démo ici (pour Windows 8.1).
Pensez à renommer le fichier en .zip (WordPress ne permet pas de hoster des zip, allez savoir pourquoi…).

Si vous êtes un grand cynique, vous me direz : « Quel intérêt de mettre le code dans le html plutôt que dans le js ? ». Au dela de la « beauté » de la chose, imaginez la quantité de code javascript pour gérer proprement le cas simple ci-dessus… par ailleurs, cette approche vous permet de rester synchro entre votre code et votre css, en reposant sur les mêmes media-queries. A l’échelle d’une application, croyez moi ça change la vie.

Notez que contrairement à ce qui se passe en CSS, vous n’avez pas d’état par défaut. Il faut donc définir soigneusement ses queries pour que les évènements se déclenchent comme prévu, sans laisser de trou.

Un exemple concret sera plus parlant. Admettons qu’on déclare les queries de la facon suivante :

<div id="listlayout" data-win-control="MCNEXT.UI.SmartListLayout" data-win-options="{
    listView: select('#mylistview'),
    layouts:{
        default : { query: '(orientation: landscape)'}, layout : WinJS.UI.GridLayout
        vert : { query: '(orientation: portrait)', layout : WinJS.UI.GridLayout, options: { orientation : 'vertical'}},
        snap : { query: '(orientation: portrait) and (max-width: 350px)', layout : WinJS.UI.ListLayout },
    }
}"></div>

on a enlevé le « min-width » de la 2e querie. En css cela n’aurait pas d’impact, mais ici la 2e query ne sera pas déclenchée systématiquement lorsque vous redimensionnez l’application snappée
(faites le test…). Prenez soin que vos plages se chevauchent correctement lorsque vous prenez une approche « responsive ».

Notre contrôle utilise des évènements sur les media queries. Pour éviter les problèmes désagréables comme les zombies (des éléments du DOM morts mais tenus vivants par ces évènements), et les fuites mémoire, il est préférable de libérer ces évènements lorsqu’on quitte la page.
Sous Windows 8.1, la destruction est gérée automatiquement car WinJS introduit un modèle de libération de mémoire. Les éléments à libérer sont marqués de la classe « win-disposable ». Lors du « unload » de la page, les éléments marqués vont être libérés automatiquement (enfin le code est dans Navigator.js…) en appelant la méthode dispose du contrôle.
Le contrôle est parfaitement utilisable sous Windows 8, la seule petite subtilité est qu’il vous faudra appeler manuellement la méthode « dispose » dans l’évènement unload de votre page.

Happy ListView

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :