Riot et Backbone, combo magique?
Ma nouvelle Ă©tape dans ma dĂ©couverte de Riot est: âest-ce que ça fonctionne correctement avec Backbone?â. En effet je prĂ©fĂšre (mais ça nâengage que moi) travailler avec plusieurs âmicroframeworksâ quâun seul âmacroframeworkâ qui lorsquâil disaparaĂźt ou change profondĂ©ment vous colle dans la mouise. Sans compter ma passion immodĂ©rĂ©e pour Backbone ;).
Modifions notre code serveur
Si vous ĂȘtes ici, câest que normalement vous avez lu le post prĂ©cĂ©dent http://k33g.github.io/2015/02/02/RIOT.html
Donc modifiez le code du fichier app.js
de cette façon:
var express = require('express');
var http = require('http');
var bodyParser = require('body-parser');
var app = express(), http_port = 3008;
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
/* on ajoute une mini base de données en mémoire */
var db = [
{id: "001", firstName:"Bob", lastName:"Morane"},
{id: "002", firstName:"John", lastName:"Doe"},
{id: "003", firstName:"Jane", lastName:"Doe"}
];
/* envoyer la liste des humains au format json */
app.get("/humans", function(req, res) {
res.send(db)
});
app.listen(http_port);
console.log("Listening on " + http_port);
Ajoutons les dépendances
Nous aurons besoin de:
- Backbone : http://backbonejs.org/backbone.js
- Underscore : http://underscorejs.org/underscore.js
- JQuery : http://code.jquery.com/jquery-2.1.3.min.js
Vous collez tout ça dans le répertoire js/vendors
votre-app/
âââ public/
| âââ js/
| | âââ tags/
| | | âââ hello-title.tag
| | âââ vendors/
| | âââ backbone.js
| | âââ underscore.js
| | âââ jquery-2.1.3.min.js
| | âââ riot.js
| | âââ compiler.js
| âââ index.html
âââ package.json
âââ app.js
Câest bon, nous somme prĂȘts pour continuer.
Pensez à déclarer les dépendances dans la page index.html
:
<script src="js/vendors/jquery-2.1.3.js"></script>
<script src="js/vendors/riot.js"></script>
<script src="js/vendors/compiler.js"></script>
<script src="js/vendors/underscore.js"></script>
<script src="js/vendors/backbone.js"></script>
La liste des humains: version simple
Lancez déjà votre application node app.js
et appelez http://localhost:3008/humans pour vérifier que vous obtenez bien un tableau de données:
[{"id":"001","firstName":"Bob","lastName":"Morane"},{"id":"002","firstName":"John","lastName":"Doe"},{"id":"003","firstName":"Jane","lastName":"Doe"}]
Dans index.html
Dans le corps de la page ajoutez le tag <humans-list></humans-list>
Au sein dâune balise <script></script>
en bas de page, ajoutez le code Backbone qui va bien:
var Kind = function() {};
Kind.extend = Backbone.Model.extend;
var HumansServices = Kind.extend({
constructor: function() {
var Human = Backbone.Model.extend({
urlRoot: "humans"
});
var Humans = Backbone.Collection.extend({model: Human, url:"humans"});
this.humansColl = new Humans()
}
});
var humansServices = new HumansServices();
/* Monter humans-list en lui passant le service */
riot.mount("humans-list",{
humansServices: humansServices
});
Création du tag humans-list
Ensuite, créez un nouveau tag dans le répertoire public/js/tags
que vous appelerez humans-list.tag
<humans-list>
<div each="{humans}">
{id} {firstName} {lastName}
</div>
var thatList = this;
var humansCollection = this.opts.humansServices.humansColl;
humansCollection.fetch().then(function() {
thatList.humans = humansCollection.toJSON();
thatList.update()
});
</humans-list>
Pensez à le déclarer dans index.html
:
<script src="js/tags/humans-list.tag" type="riot/tag"></script>
Et voilĂ , vous nâavez plus quâĂ tester dans votre navigateur:
Jusque là pas de soucis, vérifions un deuxiÚme point.
La liste des humains: version ânestedâ
Il est intĂ©ressant parfois de ne vouloir modifier (et afficher les modifications) quâun seul modĂšle de la liste sans avoir Ă recharger toute la liste (surtout si elle est longue).
Nouveau tag human-card
Du coup créons un nouveau tag dans public/js/tags
que nous appellerons human-card.tag
qui servira Ă afficher le dĂ©tail dâun modĂšle:
<human-card>
<div>{human.firstName} {human.lastName}</div>
var thisCard = this;
this.model = this.opts.model; /* je passe le modĂšle Backbone en options */
this.human = this.model.toJSON()
/* si mon modĂšle change, je mets Ă jour l'affichage */
this.opts.model.on("change", function(){
thisCard.human = thisCard.model.toJSON()
thisCard.update();
});
</human-card>
Allons modifier le tag humans-list
<humans-list>
<div each="{model, index in humans}">
<human-card model={model}></human-card>
</div>
var thatList = this;
var humansCollection = this.opts.humansServices.humansColl;
humansCollection.fetch().then(function() {
thatList.humans = humansCollection.models;
thatList.update()
});
</humans-list>
Vous avez notĂ© que lâon passe le modĂšle par le biais dâun attribut model
(model
nâest pas un mot clĂ©, je lâai choisi moi mĂȘme).
Pensez à déclarer le nouveau tag dans index.html
:
<script src="js/tags/human-card.tag" type="riot/tag"></script>
<script src="js/tags/humans-list.tag" type="riot/tag"></script>
Testez Ă nouveau dans votre navigateur: vous obtiendrez la mĂȘme chose que toute Ă lâheure, mais par contre, ouvrez la console et tapez la commande suivante:
humansServices.humansColl.at(0).set("firstName","BOBBY")
Vous prenez donc le 1er modĂšle de la collection et changez la valeur de firstName
, Ă ce moment lĂ , le trigger "change"
du modĂšle est dĂ©clenchĂ© et lâaffichage du modĂšle est mis Ă jour:
Donc pour le moment, la cohabitation avec mon framework fétiche et Riot semble se passer plutÎt pas mal. Il va falloir continuer de creuser, mais je suis plutÎt optimiste.
I <3 Riot ;)
Tweet