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
66
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
61
Beyond the Single-Page App: React and the Servers that Serve it
rjz
0
72
Typesafe(ish) React
rjz
1
660
Front-end optimization
rjz
1
420
Technical Interviewing
rjz
0
200
HTTP Security
rjz
2
150
Front-end optimization
rjz
4
240
Other Decks in Technology
See All in Technology
SaaS公式MCPサーバーをリリースして得た学び
kawamataryo
5
1.3k
Part1 GitHubってなんだろう?その2
tomokusaba
2
790
genspark_presentation.pdf
haruki_uiru
1
270
Pythonデータ分析実践試験 出題傾向や学習のポイントとテクニカルハイライト
terapyon
1
160
AWSを利用する上で知っておきたい名前解決の話
nagisa53
6
830
インフラからSREへ
mirakui
12
3.3k
経済メディア編集部の実務に小さく刺さるAI / small-ai-with-editorial
nkzn
2
420
Software Architecture in an AI-Driven World
atty303
40
16k
250510 StepFunctionのテスト自動化始めました vol.1
east_takumi
1
230
Developer 以外にこそ使って欲しい Amazon Q Developer
mita
0
150
Serverlessだからこそコードと設計にはこだわろう
kenichirokimura
3
1.1k
計測による継続的なCI/CDの改善
sansantech
PRO
7
1.4k
Featured
See All Featured
KATA
mclloyd
29
14k
Testing 201, or: Great Expectations
jmmastey
42
7.5k
Balancing Empowerment & Direction
lara
0
17
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Navigating Team Friction
lara
185
15k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Building an army of robots
kneath
305
45k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
How STYLIGHT went responsive
nonsquared
100
5.5k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.4k
GitHub's CSS Performance
jonrohan
1031
460k
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