Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Backbone & Marionette avec @xbourguignon à Soft...
Search
Philippe CHARRIERE
October 24, 2013
Programming
0
290
Backbone & Marionette avec @xbourguignon à SoftShake
Philippe CHARRIERE
October 24, 2013
Tweet
Share
More Decks by Philippe CHARRIERE
See All by Philippe CHARRIERE
The Plan v3 pour BDX.io
k33g
1
160
Le Plan
k33g
0
180
Prog Fonctionnelle 🐑
k33g
1
350
Apéro fonctionnel
k33g
0
120
Scala Facile
k33g
0
260
Golo, the Tiny Language that gives super powers
k33g
0
95
Golo, the Tiny Language that gives super powers
k33g
0
230
Apéro Fonctionnel
k33g
0
260
Programmation fonctionnelle 🐑 en JS
k33g
2
290
Other Decks in Programming
See All in Programming
5つのアンチパターンから学ぶLT設計
narihara
1
140
Node-RED を(HTTP で)つなげる MCP サーバーを作ってみた
highu
0
120
Code as Context 〜 1にコードで 2にリンタ 34がなくて 5にルール? 〜
yodakeisuke
0
120
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
610
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
620
エンジニア向け採用ピッチ資料
inusan
0
180
既存デザインを変更せずにタップ領域を広げる方法
tahia910
1
260
来たるべき 8.0 に備えて React 19 新機能と React Router 固有機能の取捨選択とすり合わせを考える
oukayuka
2
880
20250704_教育事業におけるアジャイルなデータ基盤構築
hanon52_
4
250
Is Xcode slowly dying out in 2025?
uetyo
1
240
Hypervel - A Coroutine Framework for Laravel Artisans
albertcht
1
110
dbt民主化とLLMによる開発ブースト ~ AI Readyな分析サイクルを目指して ~
yoshyum
2
240
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.4k
How STYLIGHT went responsive
nonsquared
100
5.6k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Typedesign – Prime Four
hannesfritz
42
2.7k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Facilitating Awesome Meetings
lara
54
6.4k
Rebuilding a faster, lazier Slack
samanthasiow
82
9.1k
KATA
mclloyd
30
14k
4 Signs Your Business is Dying
shpigford
184
22k
Writing Fast Ruby
sferik
628
62k
Build The Right Thing And Hit Your Dates
maggiecrowley
36
2.8k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Transcript
Backbone & Marionette Xavier Bourguignon Philippe Charrière
About Us @k33g_org Lyon Steria Golo Fan #1 @xbourguignon Genève
Hortis GenevaJUG Leader
Backbone.js @k33g_org / Lyon / Steria “tout nu”
1 librairie MVC par Jeremy Ashkenas jQuery + Underscore tous
navigateurs
1 librairie “extra légère” Backbone : 20 kb jQuery :
84 kb Underscore : 14 kb
BB = SPA Helper
Enorme communauté Nombreux plugins “sérieux”
Très simple Code facile à lire facile à “augmenter”
Backbone, c'est Play!> dans votre navigateur
BB est MVC ?
M♥ VC Backbone.Model Backbone.Collection
MVC Templates <%= something %>
MVC Backbone.View ?!*#!??? “la glue”
MVP Backbone.View model view presenter
Mais aussi Backbone.Sync Backbone.Router ...
Modèle Objet
Un modèle "interne"
Pompage var Kind = function() {}; Kind.extend = Backbone.Model.extend;
klass var TinyToon = Kind.extend({ constructor : function (firstName, lastName){
this.firstName = firstName; this.lastName = lastName; }, toString : function() { return this.firstName + " " +this.lastName } }); var babs = new TinyToon("Babs", "Bunny")
héritage var Elmyra = TinyToon.extend({ constructor : function (){ this.firstName
= "Elmyra"; this.lastName = "Duff"; Elmyra.__super__.constructor.call(this); console.log("Oh, it's so cute ♥ ♥ ♥"); }, isChasing : function(toon) { //foo } });
static var Elmyra = TinyToon.extend({ //instance members },{ //statics members
theOnlyOne : null, getInstance : function() { if(Elmyra.theOnlyOne == null) { Elmyra.theOnlyOne = new Elmyra(); } return Elmyra.theOnlyOne; } }); var elmyra = Elmyra.getInstance();
Backbone.Model Backbone.Collection Backbone.sync
var Player = Backbone.Model.extend({ urlRoot:"/players" }); var bob = new
Player({ firstName : "Bob", lastName : "Morane" }) Model
get() / set() bob.get("firstName") bob.set("firstName","Bob") bob.set({ lastName:"Morane", twitter:"@bobby" }) bob.on(
"change:lastName change:firstName", ...);
mais aussi save() fetch() destroy()
Backbone.sync Appelé à chaque lecture / écriture des modèles
Backbone.sync Par défaut : REST $.ajax()
bob.save() POST : http://domain/players save
var bob = new Player({ id:"001" }) bob.fetch() GET :
http://domain/players/001 fetch
bob.set("twitter","@bobby") bob.save() PUT : http://domain/players/001 save/update
bob.destroy() DELETE : http://domain/players/001 destroy
var Players = Backbone.Collection. extend({ url :"/players", model : Player
}); var players = new Players() Collection
players.fetch() GET : http://domain/players/ fetch : getAll
_.template()
<ol> <% _.each(players, function(player) { %> <li id="<%= player.id %>">
<%= player.firstName %> <%= player.lastName %> </li> <% }); %> </ol> Avec Underscore template
d'autres moteurs Mustache Handelbars TempoJS ...
Backbone.View Controller Presenter
var PlayersView = Backbone.View.extend({ el : "#players", initialize : function()
{ this.template = _.template($("#template").html()); }, render : function() { this.$el.html( this.template({ players:this.collection.toJSON() }) ); } });
var PlayersView = Backbone.View.extend({ /*...*/ events:{ "click :checkbox" : function(event)
{}, "click .btn-success" : function() {} } }); var playersView = new PlayersView({collection:players})
Backbone.Router
var router = Backbone.Router.extend({ routes: { "home": "index", "products/:computer": "display",
"products/:computer/:model": "display" }, index: function() { }, display: function(computer, model) { } });
1 Exemple simple 1 “blog”
Vue
Vue Modèles & Collections
Vue Modèles & Collections Contrôleur
Vue Modèles & Collections Contrôleur Go!
\o/
Plus loin: -> + commentaires
None
None
None
None
None
None
nouvelle version
Donc pas mal de code en plus, et ce n’est
pas fini ...
Memory leaks
None
None
None
Conclusion
BB != machine à tout faire
Marionette.js @xbourguigon / Genève / Hortis Make your Backbone application
dance !
1 librairie par Derick Bailey Pour aller encore plus loin
avec Backbone
Marionette = SPA with BB Helper
ItemView
MyItemView = Marionette.ItemView.extend({ template:"#my-view-template" }); var myView = new MyItemView({
model: someBBModel });
CollectionView
ItemsView = Marionette.CollectionView.extend({ itemView:MyItemView }); var myCollectionView = new ItemsView({
collection: someBBCollection });
Region
var mainRegion = new Marionette.Region({ el:"#main-container" }); var view =
new MyView(); mainRegion.show(view); var otherView = new AnotherView(); mainRegion.show(otherView);
Layout
(wrapper template) #someRegion #anotherRegion
var MyLayout = Marionette.Layout.extend({ template:"#my-layout-template", regions:{ region1:"#someRegion", region2:"#anotherRegion" } });
var layout = new MyLayout(); mainRegion.show(layout); layout.region1.show(new SomeView()); layout.region2.show(new OtherView());
Autres raffinements pour les vues
var itemView = new MyView({model: someModel}); itemView.render(); var collectionView =
newOtherView({ collection: someCollection }); collectionView.render(); automatic render
mainRegion.show(layout); layout.region1.show(new SomeView()); layout.region2.show(new OtherView()); layout.region1.show(new ThirdView()); mainRegion.show(anotherLayout); zombie killing
var myView = Marionette.ItemView.extend({ template:"#my-view-template", ui:{ mainButton: "#mainButton" }, clickButton:
function() { this.ui.mainButton.click(); } }); ui objects
var myView = Marionette.ItemView.extend({ template:"#my-view-template", modelEvents:{ "change:name":"doThing" }, doThing: function()
{ // call when the name changes ! } }); model events
var myView = Marionette.CollectionView.extend({ template:"#my-view-template", collectionEvents:{ "add":"itemAdded" }, itemAdded: function()
{ // call when the name changes ! } }); collection events
Marionette === scalable BB
None
App Sub-App Sub-App Sub-App
Découpage en modules
Application
(function(global) { var MyApp = new Marionette.Application(); MyApp.addRegions({ mainRegion:"#main" });
MyApp.on("initialize.after", function() { Backbone.history.start(); }) global.MyApp = MyApp; })(window)
<script src="/js/app.js" /> <script src="/js/itemView.js" /> <script> $(function(){ MyApp.start(); });
</script>
Module
MyApp.module("myModule", function(Mod, App, BB, Marionette, $, ...) { var SomeModel
= Backbone.Model.extend({...}); var ItemView = Marionette.ItemView.extend ({...}); var model = new SomeModel(); ...
… Mod.initializer(function() { var promise = model.fetch(); $.when(promise).then(function(){ var view
= new SomeView(); MyApp.mainRegion.show(view); }); }); });
MyApp.module("SubApp", function() { this.startWithParent = false; this.addInitializer(function() {...}) } MyApp.module("SubApp").start();
MyApp.module("myModule").stop(); start / stop
Controller
WTF ?
Mediator All purpose object Public API for component controller
var ThatThing = Marionette.Controller.extend({ doStuff: function() { ... } });
Blog Marionette version
Questions ?
On a plus le temps :-(
Merci
@k33g_org @xbourguignon