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
Oracle Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
3
200
MySQLのSpatial(GIS)機能をもっと充実させたい ~ MyNA望年会2025LT
sakaik
0
160
Oracle Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
2
450
AgentCore BrowserとClaude Codeスキルを活用した 『初手AI』を実現する業務自動化AIエージェント基盤
ruzia
7
2k
株式会社ビザスク_AI__Engineering_Summit_Tokyo_2025_登壇資料.pdf
eikohashiba
1
130
Bedrock AgentCore Evaluationsで学ぶLLM as a judge入門
shichijoyuhi
2
290
オープンソースKeycloakのMCP認可サーバの仕様の対応状況 / 20251219 OpenID BizDay #18 LT Keycloak
oidfj
0
240
Strands Agents × インタリーブ思考 で変わるAIエージェント設計 / Strands Agents x Interleaved Thinking AI Agents
takanorig
6
2.3k
Bedrock AgentCore Memoryの新機能 (Episode) を試してみた / try Bedrock AgentCore Memory Episodic functionarity
hoshi7_n
2
2.1k
MySQLとPostgreSQLのコレーション / Collation of MySQL and PostgreSQL
tmtms
1
1.4k
Claude Codeを使った情報整理術
knishioka
15
11k
Claude Skillsの テスト業務での活用事例
moritamasami
1
120
Featured
See All Featured
Paper Plane (Part 1)
katiecoart
PRO
0
2.3k
The agentic SEO stack - context over prompts
schlessera
0
570
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
0
200
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.5k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
55k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.8k
Ethics towards AI in product and experience design
skipperchong
1
140
How to train your dragon (web standard)
notwaldorf
97
6.5k
The Pragmatic Product Professional
lauravandoore
37
7.1k
Designing for Timeless Needs
cassininazir
0
100
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
29
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