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
Interop! Building a better Backbone.View
Search
RJ Zaworski
September 12, 2014
Technology
0
95
Interop! Building a better Backbone.View
RJ Zaworski
September 12, 2014
Tweet
Share
More Decks by RJ Zaworski
See All by RJ Zaworski
Computing Lessons from the Atomic Age: Complexity, Safety, and Ethics
rjz
0
87
Beyond the Single-Page App: React and the Servers that Serve it
rjz
0
91
Typesafe(ish) React
rjz
1
690
Front-end optimization
rjz
1
460
Technical Interviewing
rjz
0
230
HTTP Security
rjz
2
180
Front-end optimization
rjz
4
270
Other Decks in Technology
See All in Technology
Strands AgentsとNova 2 SonicでS2Sを実践してみた
yama3133
1
2k
半年で、AIゼロ知識から AI中心開発組織の変革担当に至るまで
rfdnxbro
0
150
「もしもデータ基盤開発で『強くてニューゲーム』ができたなら今の僕はどんなデータ基盤を作っただろう」
aeonpeople
0
250
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
9.9k
2025-12-27 Claude CodeでPRレビュー対応を効率化する@機械学習社会実装勉強会第54回
nakamasato
4
1.2k
Identity Management for Agentic AI 解説
fujie
0
500
AI時代のワークフロー設計〜Durable Functions / Step Functions / Strands Agents を添えて〜
yakumo
3
2.4k
MySQLのSpatial(GIS)機能をもっと充実させたい ~ MyNA望年会2025LT
sakaik
0
150
SQLだけでマイグレーションしたい!
makki_d
0
1.2k
AR Guitar: Expanding Guitar Performance from a Live House to Urban Space
ekito_station
0
260
20251218_AIを活用した開発生産性向上の全社的な取り組みの進め方について / How to proceed with company-wide initiatives to improve development productivity using AI
yayoi_dd
0
780
100以上の新規コネクタ提供を可能にしたアーキテクチャ
ooyukioo
0
280
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
42
2.9k
A Tale of Four Properties
chriscoyier
162
23k
Claude Code のすすめ
schroneko
67
210k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
93
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
130
What's in a price? How to price your products and services
michaelherold
246
13k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
860
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
0
210
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
130
Leo the Paperboy
mayatellez
0
1.3k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
410
Transcript
Interop! Building a better Backbone.View rj zaworski, versal inc. ·
@rjzaworski · github.com/rjz
Let’s Talk Backbone MVC (but mostly “M”) ★ Views: the
DOM ★ Controllers: ?
Let’s Talk Backbone Models are: ★ consistent (RESTful) ★ small
★ event-driven
Let’s Talk Backbone For everything else, frameworks ★ Thorax (templating,
structure, data-binding) ★ Marionette (structure) ★ ...and a cast of thousands
The Goal 1. Composable 2. Transparent 3. Data-driven 4. Portable
Composable Large UIs built of smaller components ★ focused concerns
★ predictable life-cycles
Transparent Both concern and implementation are readily apparent and easy
to follow
Data-driven ★ State lives in the model ★ Views respond
to model changes
Portable Views can be reused ★ outside the host application
★ outside each other ★ outside Backbone
Ex. 1: Backbone Goal: render a <figure> from a Backbone.Model
.
Ex. 1: Backbone Goal: render a <figure> from a Backbone.Model
. var template = _.template([ '<img src="<%- image %>" />', '<figcaption><%- title % ></figcaption>' ].join('')) var FigureView = Backbone.View.extend({ tagName: 'figure', render: function () { var attrs = this.model.toJSON(); this.el.innerHTML = template(attrs); return this; } });
Ex. 1: Backbone Goal: decompose <figure> into an <img> and
a <figcaption>
Ex. 1: Backbone Goal: decompose <figure> into an <img> and
a <figcaption> var Image = Backbone.View.extend({ tagName: 'img', // ... }); var Figcaption = Backbone.View.extend({ tagName: 'figcaption', // ... }); // in parent's render() method this.$el.empty() .append(imageView.render().el) .append(figcaptionView.render().el);
Ex. 1: Backbone ★ manipulate DOM directly ★ what about
old state? var Image = Backbone.View.extend({ tagName: 'img', // ... }); var Figcaption = Backbone.View.extend({ tagName: 'figcaption', // ... }); // in parent's render() method this.$el.empty() .append(imageView.render().el) .append(figcaptionView.render().el);
Ex. 1: Backbone Goal: update <figcaption> when model changes
Ex. 1: Backbone Goal: update <figcaption> when model changes var
Figcaption = Backbone.View.extend({ initialize: function () { this.listenTo( this.model, 'change', this.onModelChange ); }, onModelChange: function () { alert('changed'); this.render(); }, // ...
Ex. 1: Backbone What if we remove the parent view?
var Figure = Backbone.View.extend({ events: { 'click .js-close': 'onCloseClick' }, onCloseClick: function (e) { e.preventDefault(); this.$el.remove(); }, // ... }
Ex. 1: Backbone What if we remove the parent view?
Events stay bound! var Figcaption = Backbone.View.extend({ initialize: function () { this.listenTo( this.model, 'change', this.onModelChange ); }, onModelChange: function () { alert('changed'); this.render(); }, // ...
Back to the goal... 1. Composable? 2. Transparent? 3. Data-driven?
4. Portable?
We can make our lives easier Interop!
React.js ★ UI-centric ★ The “V” in MVC - no
models ★ We don’t need JSX
React.js Advantages ★ One-way data flow ★ Managed lifecycle ★
Immediate mode
Ex. 2: Backbone + React React Children... var ImageView =
React.createClass({ render: function () { return React.DOM.img({ src: this.props.image }); } }); var FigcaptionView = React.createClass({ render: function () { return React.DOM.figcaption(null, this.props.title ); } });
Ex. 2: Backbone + React ...with a Backbone.View parent var
imageEl = $('<div />')[0]; var figcaptionEl = $('<div />')[0]; this.$el.empty() .append(imageEl) .append(figcaptionEl); React.renderComponent( ImageView(this.model.toJSON()), imageEl ); React.renderComponent( FigcaptionView(this.model.toJSON()), figcaptionEl );
Ex. 2: Backbone + React Container <div> aside, ★ Complexity
contained in parent ★ Children are easy to work with! ★ No child zombies
Wire Backbone data to React UI It’s just an “M”
and a “V”: ★ Make friends with toJSON() ★ Keep the interface small
Ex. 3: React Goal: render a (React-powered) <figure> from a
Backbone.Model . var FigureView = React.createClass({ render: function () { return React.DOM.figure({}, [ ImageView(this.props), FigcaptionView(this.props) ]); } }); var props = model.toJSON(); React.renderComponent( new FigureView(props), document.querySelector('.container') );
Ex. 3: React ★ Complexity contained in top-level app ★
All views are easy to work with! ★ No zombies
Ex. 3: React ...and the interface is tiny! var FigureView
= React.createClass({ render: function () { return React.DOM.figure({}, [ ImageView(this.props), FigcaptionView(this.props) ]); } }); var props = model.toJSON(); React.renderComponent( new FigureView(props), document.querySelector('.container') );
Back to the goal... 1. Composable? 2. Transparent? 3. Data-driven?
4. Portable?
Web Components Our simple view fits into the DOM <figure>
<img src="images/milo.jpg" /> <figcaption>Milo</figcaption> </figure>
Web Components What if we could wrap any view up
like this? <figure> <img src="images/milo.jpg" /> <figcaption>Milo</figcaption> </figure> <my-figure title="Milo" image="images/milo.jpg"> </my-figure>
Web Components “...encapsulated and interoperable custom elements that extend HTML
itself” (https://www.polymer-project.org/)
Web Components The bad news: they’re not ready yet ★
Limited native support ★ Implemented via Polymer, X-Tags
Ex. 4: Web Components Register <my-figure> var proto = Object.create(HTMLElement.prototype);
document.registerElement('my-figure', { prototype: proto });
Ex. 4: Web Components proto.createdCallback = function () { var
img = this.img = document.createElement('img'); var shadow = this.createShadowRoot(); shadow.appendChild(img); }; proto.attributeChangedCallback = function (key) { switch (key) { case 'image': this.img.setAttribute('src', this.getAttribute('image')); break; } };
Ex. 4: Web Components Sending in the model... var figure
= document.createElement('my-figure'); figure.setAttribute('image', model.get('image')); $('body').appendChild(figure);
Ex. 4: Web Components Sending in the model... var figure
= document.createElement('my-figure'); figure.setAttribute('image', model.get('image')); $('body').appendChild(figure); <body> <my-figure image="images/milo.jpg"></my-figure> </body>
Ex. 4: Web Components Just like that, we’re back to
the DOM. model.on('change', function () { $('my-figure').attr(model.toJSON()); });
Back to the goal... 1. Composable? 2. Transparent? 3. Data-driven?
4. Portable?
Thank you! rj zaworski · @rjzaworski · github.com/rjz Code samples:
github.com/rjz/backbone-interop