Slide 1

Slide 1 text

Standley Chasm by Jon Wiley DIVIDE CLIENT-SIDE SERVER-SIDE Bridging the @smcbride #fluentconf #divided

Slide 2

Slide 2 text

Sean McBride

Slide 3

Slide 3 text

Sean McBride Engineer & Web Developer

Slide 4

Slide 4 text

Sean McBride Engineer & Web Developer User Experience Web Developer

Slide 5

Slide 5 text

empty conference room by MNicoleM

Slide 6

Slide 6 text

? empty conference room by MNicoleM

Slide 7

Slide 7 text

DIVIDE? What do I mean by @smcbride #fluentconf #divided

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

FAST FUN ACCESSIBLE

Slide 11

Slide 11 text

CLIENT-SIDE SERVER-SIDE

Slide 12

Slide 12 text

CLIENT-SIDE SERVER-SIDE Ruby jQuery Rails

Slide 13

Slide 13 text

CLIENT-SIDE SERVER-SIDE Ruby ? Rails

Slide 14

Slide 14 text

CLIENT-SIDE SERVER-SIDE

Slide 15

Slide 15 text

CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Application Behavior

Slide 16

Slide 16 text

CLIENT-SIDE SERVER-SIDE Java Ruby Python JS Coffee Libraries API Application

Slide 17

Slide 17 text

CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs Application Application

Slide 18

Slide 18 text

Application Application CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs + SERVES JS AND NO-JS CLIENTS

Slide 19

Slide 19 text

Application Application CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs + GREATER UX FLEXIBILITY

Slide 20

Slide 20 text

Application Application CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs :( CODE DUPLICATION

Slide 21

Slide 21 text

Application Application CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs :( MOVING DATA BACK AND FORTH

Slide 22

Slide 22 text

CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs Application Application

Slide 23

Slide 23 text

CLIENT-SIDE SERVER-SIDE JS Coffee Application Application

Slide 24

Slide 24 text

CLIENT-SIDE SERVER-SIDE JS Coffee Node.js JS Coffee Node.js Application Application

Slide 25

Slide 25 text

CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs Application Application

Slide 26

Slide 26 text

Application Application CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs MVVM Model–View–ViewModel

Slide 27

Slide 27 text

Application Application CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs DECLARATIVE BINDINGS

Slide 28

Slide 28 text

Application Application CLIENT-SIDE SERVER-SIDE Java Python Ruby JS Coffee Libs CLIENT/SERVER RENDERING

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

MVVM Better organization with @smcbride #fluentconf #divided

Slide 31

Slide 31 text

JAVASCRIPT LIBRARIES

Slide 32

Slide 32 text

Backbone.js SproutCore Sammy.js Spine.js Cappuccino Knockout.js Javascript MVC Google Web Toolkit Google Closure Ember.js Angular.js Batman.js Meteor Derby JAVASCRIPT LIBRARIES

Slide 33

Slide 33 text

MVC MVP MVVM

Slide 34

Slide 34 text

MVC Model + View + Controller MVP Model + View + Presenter MVVM Model + View + ViewModel

Slide 35

Slide 35 text

MVC Model + View + Controller MVP Model + View + Presenter MVVM Model + View + ViewModel

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

CLIENT-SIDE SERVER-SIDE

Slide 38

Slide 38 text

CLIENT-SIDE SERVER-SIDE MVC

Slide 39

Slide 39 text

CLIENT-SIDE SERVER-SIDE MVC VVM M

Slide 40

Slide 40 text

CLIENT-SIDE SERVER-SIDE MVC VVM

Slide 41

Slide 41 text

CLIENT-SIDE SERVER-SIDE Model (ActiveRecord)

Slide 42

Slide 42 text

CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) Controller (ActionController)

Slide 43

Slide 43 text

CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) ViewModel (JS + Knockout) Controller (ActionController)

Slide 44

Slide 44 text

CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) ViewModel (JS + Knockout) ViewModel Adapter Controller (ActionController) (JSON)

Slide 45

Slide 45 text

CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) ViewModel (JS + Knockout) Template (HTML + Bindings) ViewModel Adapter Controller (ActionController) (JSON)

Slide 46

Slide 46 text

Template (HTML + Bindings) CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) ViewModel (JS + Knockout) ViewModel Adapter Controller (ActionController) (JSON)

Slide 47

Slide 47 text

Ferrying data from server to client VIEWMODEL ADAPTERS

Slide 48

Slide 48 text

Ferrying data from server to client VIEWMODEL ADAPTERS class User < ActiveRecord::Base validates_presence_of :billing_name end Server-side

Slide 49

Slide 49 text

Ferrying data from server to client VIEWMODEL ADAPTERS class User < ActiveRecord::Base validates_presence_of :billing_name end module ViewModel::Person < ViewModel::Base def self.from_user(user) self.new( :name => user.billing_name ) end end Server-side

Slide 50

Slide 50 text

Ferrying data from server to client VIEWMODEL ADAPTERS class User < ActiveRecord::Base validates_presence_of :billing_name end module ViewModel::Person < ViewModel::Base def self.from_user(user) self.new( :name => user.billing_name ) end end Server-side self.from_twitter self.from_vendor self.from_admin

Slide 51

Slide 51 text

Ferrying data from server to client VIEWMODEL ADAPTERS user = User.find(1) person = ViewModel::Person.from_user(user) person.to_json # => {"name": "Sean McBride"} Server-side

Slide 52

Slide 52 text

function Person(name) { this.name = ko.observable(name); } Client-side Ferrying data from server to client VIEWMODEL ADAPTERS

Slide 53

Slide 53 text

function Person(name) { this.name = ko.observable(name); } Person.prototype.update = function(data) { this.name(data["name"]); } Client-side Ferrying data from server to client VIEWMODEL ADAPTERS

Slide 54

Slide 54 text

The MVVM pattern helps to ORGANIZE CLIENT AND SERVER CODE

Slide 55

Slide 55 text

The MVVM pattern helps to MOVE DATA BACK AND FORTH

Slide 56

Slide 56 text

The MVVM pattern helps to REDUCE DUPLICATION

Slide 57

Slide 57 text

The MVVM pattern helps to ORGANIZE DUPLICATION

Slide 58

Slide 58 text

DECLARATIVE BINDINGS Easily build dynamic UIs with @smcbride #fluentconf #divided

Slide 59

Slide 59 text

Backbone.js SproutCore Sammy.js Spine.js Cappuccino Knockout.js Javascript MVC Google Web Toolkit Google Closure Ember.js Angular.js Batman.js Meteor Derby DECLARATIVE BINDINGS

Slide 60

Slide 60 text

Backbone.js SproutCore Sammy.js Spine.js Cappuccino Knockout.js Javascript MVC Google Web Toolkit Google Closure Ember.js Angular.js Batman.js Meteor Derby DECLARATIVE BINDINGS

Slide 61

Slide 61 text

function Person(name) { this.name = ko.observable(name); } Client-side

Slide 62

Slide 62 text

function Person(name) { this.name = ko.observable(name); }
Full name:
Client-side Template

Slide 63

Slide 63 text

function Person(name) { this.name = ko.observable(name); }
Full name:
Full name: Client-side Template

Slide 64

Slide 64 text

function Person(name) { this.name = ko.observable(name); }
Full name:
var me = new Person("Sean McBride"); ko.applyBindings(me, document.getElementById("person")); Full name: Client-side Template Client-side

Slide 65

Slide 65 text

function Person(name) { this.name = ko.observable(name); }
Full name:
var me = new Person("Sean McBride"); ko.applyBindings(me, document.getElementById("person")); Full name: Sean McBride Client-side Template Client-side

Slide 66

Slide 66 text

function Person(name) { this.name = ko.observable(name); }
Full name:
var me = new Person("Sean McBride"); ko.applyBindings(me, document.getElementById("person")); Full name: Sean McBride me.name("Oscar the Grouch"); Client-side Template Client-side

Slide 67

Slide 67 text

function Person(name) { this.name = ko.observable(name); }
Full name:
var me = new Person("Sean McBride"); ko.applyBindings(me, document.getElementById("person")); Full name: Oscar the Grouch me.name("Oscar the Grouch"); Client-side Template Client-side

Slide 68

Slide 68 text

Full name:
Verify name:
Template

Slide 69

Slide 69 text

Full name: Verify name: Sean McBride
Full name:
Verify name:
Sean McBride Template

Slide 70

Slide 70 text

Full name: Verify name:
Full name:
Verify name:
Template

Slide 71

Slide 71 text

Full name: Verify name:
Full name:
Verify name:
Oscar the Grouch Oscar the Grouch Template

Slide 72

Slide 72 text

Declarative bindings mean TEMPLATES ARE JUST HTML

Slide 73

Slide 73 text

Declarative bindings mean NO MORE MESSY RENDER METHODS

Slide 74

Slide 74 text

Declarative bindings mean DON’T THINK ABOUT UPDATING

Slide 75

Slide 75 text

CLIENT/SERVER RENDERING Reduce duplication with @smcbride #fluentconf #divided

Slide 76

Slide 76 text

CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) ViewModel (JS + Knockout) Template (HTML + Bindings) ViewModel Adapter Controller (ActionController) (JSON)

Slide 77

Slide 77 text

Template (HTML + Bindings) CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) ViewModel (JS + Knockout) ViewModel Adapter Controller (ActionController) (JSON)

Slide 78

Slide 78 text

class ViewModel::Person < ViewModel::Base def self.from_user(user) self.new( :name => user.billing_name ) end end Server-side

Slide 79

Slide 79 text

class ViewModel::Person < ViewModel::Base def self.from_user(user) self.new( :name => user.billing_name ) end end person = ViewModel::Person.from_user(User.get(1)) Server-side

Slide 80

Slide 80 text

class ViewModel::Person < ViewModel::Base def self.from_user(user) self.new( :name => user.billing_name ) end end person = ViewModel::Person.from_user(User.get(1)) render_client_side_template "person", :object => person Server-side

Slide 81

Slide 81 text

class ViewModel::Person < ViewModel::Base def self.from_user(user) self.new( :name => user.billing_name ) end end person = ViewModel::Person.from_user(User.get(1)) render_client_side_template "person", :object => person Server-side Our helper Template name ViewModel adapter

Slide 82

Slide 82 text

How to render DECLARATIVE BINDINGS on the server?

Slide 83

Slide 83 text

Bindings modify the DOM

Slide 84

Slide 84 text

Bindings modify the DOM NOKOGIRI

Slide 85

Slide 85 text

Bindings modify the DOM NOKOGIRI Bindings can have JS expressions

Slide 86

Slide 86 text

Bindings modify the DOM NOKOGIRI Bindings can have JS expressions JOHNSON (SpiderMonkey)

Slide 87

Slide 87 text

1. Get the template source

Slide 88

Slide 88 text

1. Get the template source 2. Evaluate all bindings with ViewModel data

Slide 89

Slide 89 text

1. Get the template source 2. Evaluate all bindings with ViewModel data 3. Turn template into DOM fragment

Slide 90

Slide 90 text

1. Get the template source 2. Evaluate all bindings with ViewModel data 3. Turn template into DOM fragment 4. Execute each binding with values to modify DOM

Slide 91

Slide 91 text

1. Get the template source 2. Evaluate all bindings with ViewModel data 3. Turn template into DOM fragment 4. Execute each binding with values to modify DOM 5. Output HTML

Slide 92

Slide 92 text

Using Johnson server-side to EVALUATE BINDINGS

Slide 93

Slide 93 text

Using Johnson server-side to EVALUATE BINDINGS Server-side Johnson.evaluate < { "text" => "Sean McBride" }

Slide 94

Slide 94 text

Using Nokogiri server-side to APPLY BINDINGS

Slide 95

Slide 95 text

Using Nokogiri server-side to APPLY BINDINGS Client-side

Slide 96

Slide 96 text

Using Nokogiri server-side to APPLY BINDINGS Client-side ko.bindingHandlers['text'] = { 'init': function(element, valueAccessor) { // Set text initially }, 'update': function (element, valueAccessor) { // Update text when value changes } };

Slide 97

Slide 97 text

Using Nokogiri server-side to APPLY BINDINGS Client-side ko.bindingHandlers['text'] = { 'init': function(element, valueAccessor) { // Set text initially }, 'update': function (element, valueAccessor) { // Update text when value changes } }; Update is used on the client, but we don’t need it on the server!

Slide 98

Slide 98 text

Using Nokogiri server-side to APPLY BINDINGS Server-side bindings.register "text" do |element, value| element.content = value.to_s end

Slide 99

Slide 99 text

Client/server rendering SERVES JS AND NO-JS CLIENTS

Slide 100

Slide 100 text

Client/server rendering REDUCES DUPLICATION

Slide 101

Slide 101 text

Client/server rendering CAN SLOW THINGS DOWN

Slide 102

Slide 102 text

Client/server rendering CAN BE DISABLED FOR JS CLIENTS

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

PUTTING IT ALL TOGETHER Wrapping up by @smcbride #fluentconf #divided

Slide 105

Slide 105 text

Template (HTML + Bindings) CLIENT-SIDE SERVER-SIDE Model (ActiveRecord) ViewModel (JS + Knockout) ViewModel Adapter Controller (ActionController) (JSON)

Slide 106

Slide 106 text

CLIENT-SIDE SERVER-SIDE

Slide 107

Slide 107 text

CLIENT-SIDE SERVER-SIDE u = User.find(1)

Slide 108

Slide 108 text

CLIENT-SIDE SERVER-SIDE u = User.find(1) p = ViewModel::Person .from_user(u)

Slide 109

Slide 109 text

CLIENT-SIDE SERVER-SIDE u = User.find(1) p = ViewModel::Person .from_user(u) render "person", :object => p

Slide 110

Slide 110 text

CLIENT-SIDE SERVER-SIDE (JSON) u = User.find(1) p = ViewModel::Person .from_user(u) p.to_json var p = new Person(); p.update(jsonData); render "person", :object => p

Slide 111

Slide 111 text

CLIENT-SIDE SERVER-SIDE (JSON) u = User.find(1) p = ViewModel::Person .from_user(u) p.to_json var p = new Person(); p.update(jsonData); ko.applyBindings(p, el); render "person", :object => p

Slide 112

Slide 112 text

CLIENT-SIDE SERVER-SIDE MVC VM MV

Slide 113

Slide 113 text

CLIENT-SIDE SERVER-SIDE MVC VM V

Slide 114

Slide 114 text

CLIENT-SIDE SERVER-SIDE MVC VM

Slide 115

Slide 115 text

FAST FUN ACCESSIBLE

Slide 116

Slide 116 text

DIVIDE CLIENT-SIDE SERVER-SIDE Bridging the [email protected] seanmcb.com/client-server-divide MVVM DECLARATIVE BINDINGS CLIENT/SERVER RENDERING @smcbride #fluentconf #divided