Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Backbone & Marionette avec @xbourguignon à Soft...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Philippe CHARRIERE
October 24, 2013
Programming
290
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Backbone & Marionette avec @xbourguignon à SoftShake
Philippe CHARRIERE
October 24, 2013
More Decks by Philippe CHARRIERE
See All by Philippe CHARRIERE
The Plan v3 pour BDX.io
k33g
1
210
Le Plan
k33g
0
220
Prog Fonctionnelle 🐑
k33g
1
400
Apéro fonctionnel
k33g
0
130
Scala Facile
k33g
0
300
Golo, the Tiny Language that gives super powers
k33g
0
150
Golo, the Tiny Language that gives super powers
k33g
0
310
Apéro Fonctionnel
k33g
0
280
Programmation fonctionnelle 🐑 en JS
k33g
2
300
Other Decks in Programming
See All in Programming
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
240
AIとGame Jamで、ゲームを完成させた話
takahirosaeki
0
120
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
130
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
6
1.7k
新卒PdEのリアル
ryu1013
1
490
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
110
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
56
38k
自分的「カンファレンスの楽しみ方」
syumai
0
200
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
210
業務時間外もAIに働いてもらう話
colorful12
3
10k
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2.1k
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
450
Featured
See All Featured
How to Ace a Technical Interview
jacobian
281
24k
Speed Design
sergeychernyshev
33
2.1k
Git: the NoSQL Database
bkeepers
PRO
432
67k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
30 Presentation Tips
portentint
PRO
1
390
WENDY [Excerpt]
tessaabrams
13
39k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
930
We Are The Robots
honzajavorek
0
370
Testing 201, or: Great Expectations
jmmastey
46
8.3k
The Invisible Side of Design
smashingmag
301
52k
Tell your own story through comics
letsgokoyo
1
1.1k
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