Skip to content

Instantly share code, notes, and snippets.

@gre
Last active August 29, 2015 14:21
Show Gist options
  • Save gre/577a18e9e88b73993256 to your computer and use it in GitHub Desktop.
Save gre/577a18e9e88b73993256 to your computer and use it in GitHub Desktop.
virtual-dom & fluxx CheatSheet

virtual-dom

https://github.com/Matt-Esch/virtual-dom

var h = require("virtual-dom/h");
// h est similaire à React.createElement :

h("div.someClass", { title: "un attribut DOM", onclick: f, ... }, [
  h("a", { href: "url" }, "Ceci est un lien"),
  h("span", "on peut omettre le deuxième paramètre"),
  h("div", [ /* enfant de la sous-div */ ])
]);

Fluxx

https://github.com/AlexGalays/fluxx

Créer un object d'actions

var Action = require('fluxx').Action;
var actions = Action.create(
  "add",
  "remove",
  "uneAutreAction"
);

Utiliser ces actions (déclencher l'action)

actions.add(objetAAjouter);

actions.remove(objetARetirer);

actions.uneAutreAction(); // cela ne prends pas forcément de paramètre

Implémenter un Store qui réagit à ces actions

var Store = require('fluxx').Store;
var store = Store(function (on) {
  
  // L'ensemble des états vivent ici
  var list = [];
  
  // Maintenant on réagit à des actions pour faire muter les états
  
  on(actions.add, function (objetAAjouter) {
    list.push(objetAAjouter);
  });
  on(actions.remove, function (objetAAjouter) {
    removeFromList(list, objetAAjouter);
  });
  on(actions.uneAutreAction, function () {
    console.log("une autre action");
  });
  
  // On retourne l'API exposé dans store
  return {
    getList: function () {
      return list;
    }
  };
});
  • Nous pouvons utiliser store.getList() pour récupérer l'état du store.
  • A chaque fois qu'une action est appelé, la fonction f attaché avec on(action, f) est appelé.

Utiliser fluxx et virtual-dom

// rend la vue pour un état donné
function render () {
  // on récupère tous les états qu'on a besoin pour nos rendus
  var list = storeA.getList();
  var value = storeB.getValue();
  
  // on retourne une représentation du dom
  return h("div", [
    h("h1", value),
    h("ul", 
      list.map(function (element) {
        return h("li", element);
      })
    )
  ]);
}

L'idée est d'appeler cette fonction de rendu à chaque fois qu'un des états à changé. Pour simplifier on peut considérer que n'importe quel changement d'un store invalide l'affichage et donc doit provoquer un re-rendu complet.

Pour se faire on peut utiliser rendering.js.

rendering.js

Rendering abstrait toute la complexité de virtual-dom (diff, patch, create) et fait la glue avec fluxx.

var rendering = require("./rendering");
rendering.auto(storeA, storeB)(render);

Nous devons donner à rendering.auto l'ensemble des stores sur lesquels la vue dépendent. Ainsi, cette fonction appelera render dès qu'un des stores s'est remis à jour (parce qu'il a réagit à une action).

var Store = require('fluxx').Store;
var raf = require("raf");
var diff = require('virtual-dom/diff');
var patch = require('virtual-dom/patch');
var createElement = require('virtual-dom/create-element');
// adapted from @AlexGalays' code
function destroy(el, currentVDOM) {
patch(el, diff(currentVDOM, null));
}
function manual() {
var el, currentVdom, nextRedraw;
function update(vdom) {
if (nextRedraw) raf.cancel(nextRedraw);
nextRedraw = raf(function () {
if (typeof vdom === "function") vdom = vdom();
if (!el) {
el = createElement(vdom);
document.body.appendChild(el);
}
else {
var patches = diff(currentVdom, vdom);
el = patch(el, patches);
}
currentVdom = vdom;
nextRedraw = null;
});
}
update.stop = function() {
if (nextRedraw) raf.cancel(nextRedraw);
if (!el) return;
destroy(el, currentVdom);
};
return update;
}
function auto() {
var stores = arguments;
return function(renderFn) {
var _unsub, _update;
function update() {
_update(renderFn);
}
function stop() {
_update.stop();
_unsub();
}
_update = manual();
_unsub = Store.onChange.apply(null, stores)(update);
update();
return stop;
};
}
module.exports = {
manual: manual,
auto: auto,
destroy: destroy
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment