95
Aplicações dinâmicas em Rails

Aplicacoes dinamicas Rails com Backbone

Embed Size (px)

DESCRIPTION

Apresentação na RubyConfBR sob

Citation preview

Page 1: Aplicacoes dinamicas Rails com Backbone

Aplicações dinâmicas em

Rails

Page 2: Aplicacoes dinamicas Rails com Backbone
Page 4: Aplicacoes dinamicas Rails com Backbone
Page 5: Aplicacoes dinamicas Rails com Backbone

Backbone é uma estrutura para aplicações que fazem uso pesado de JavaScript, e

conecta-se a sua aplicação por uma interface RESTful.

Page 6: Aplicacoes dinamicas Rails com Backbone
Page 7: Aplicacoes dinamicas Rails com Backbone
Page 8: Aplicacoes dinamicas Rails com Backbone

Backbone.Model

Page 9: Aplicacoes dinamicas Rails com Backbone

var MyModel = Backbone.Model.extend({})

Page 10: Aplicacoes dinamicas Rails com Backbone

var MyModel = Backbone.Model.extend({})

save([attributes],[options])

Page 11: Aplicacoes dinamicas Rails com Backbone

var MyModel = Backbone.Model.extend({})

save([attributes],[options])

POST PUT

Page 12: Aplicacoes dinamicas Rails com Backbone

var MyModel = Backbone.Model.extend({})

save([attributes],[options])

fetch([options])

Page 13: Aplicacoes dinamicas Rails com Backbone

var MyModel = Backbone.Model.extend({})

save([attributes],[options])

fetch([options]) setInterval(function(){ model.fetch();

}, 10000);

Page 14: Aplicacoes dinamicas Rails com Backbone

var MyModel = Backbone.Model.extend({})

save([attributes],[options])

fetch([options]) validate(attributes)

Page 15: Aplicacoes dinamicas Rails com Backbone

var Chapter = Backbone.Model.extend({ validate: function(attrs) { if (attrs.end < attrs.start) { return "can't end before it starts"; } }});

var one = new Chapter({title : "Chapter One: The Beginning"

});

one.bind("error", function(model, error) {alert(model.get("title") + " " + error);

});

one.set({start: 15,

end: 10 });

Page 16: Aplicacoes dinamicas Rails com Backbone

var Chapter = Backbone.Model.extend({ validate: function(attrs) { if (attrs.end < attrs.start) { return "can't end before it starts"; } }});

var one = new Chapter({title : "Chapter One: The Beginning"

});

one.bind("error", function(model, error) {alert(model.get("title") + " " + error);

});

one.set({start: 15,

end: 10 });

Page 17: Aplicacoes dinamicas Rails com Backbone

Backbone.Model

Page 18: Aplicacoes dinamicas Rails com Backbone

Backbone.Model

Backbone.Collection

Page 19: Aplicacoes dinamicas Rails com Backbone

var Library = Backbone.Collection.extend({ model: Book});

Page 20: Aplicacoes dinamicas Rails com Backbone

var Library = Backbone.Collection.extend({ model: Book});

add(models, [options])

Page 21: Aplicacoes dinamicas Rails com Backbone

var Library = Backbone.Collection.extend({ model: Book});

add(models, [options]) url()

Page 22: Aplicacoes dinamicas Rails com Backbone

var Library = Backbone.Collection.extend({ model: Book});

add(models, [options]) url()url: '/library'

Page 23: Aplicacoes dinamicas Rails com Backbone

var Library = Backbone.Collection.extend({ model: Book});

add(models, [options]) url()

fetch([options])

Page 24: Aplicacoes dinamicas Rails com Backbone

var Library = Backbone.Collection.extend({ model: Book});

add(models, [options]) url()

fetch([options]) Library.fetch()

GET '/library'

Page 25: Aplicacoes dinamicas Rails com Backbone

var Library = Backbone.Collection.extend({ model: Book});

add(models, [options]) url()

fetch([options]) create(attributes, [options])

Page 26: Aplicacoes dinamicas Rails com Backbone

var alibrary = new Library;var book = alibrary.create({

title: "A book",author: "Someone"

})

Page 27: Aplicacoes dinamicas Rails com Backbone

Backbone.Model

Backbone.Collection

Page 28: Aplicacoes dinamicas Rails com Backbone

Backbone.Model

Backbone.Collection

Backbone.Router

Page 29: Aplicacoes dinamicas Rails com Backbone

var Workspace = Backbone.Router.extend({

routes: { "help": "help", "search/:query": "search", "search/:query/p:page": "search" },

help: function() {},

search: function(query, page) {}

});

Page 30: Aplicacoes dinamicas Rails com Backbone

var Workspace = Backbone.Router.extend({

routes: { "help": "help", "search/:query": "search", "search/:query/p:page": "search" },

help: function() {},

search: function(query, page) {}

});

#help#search/felix#search/felix/p2

Page 31: Aplicacoes dinamicas Rails com Backbone

var Workspace = Backbone.Router.extend({

routes: { "help": "help", "search/:query": "search", "search/:query/p:page": "search" },

help: function() {},

search: function(query, page) {}

});

#help#search/felix#search/felix/p2

Page 32: Aplicacoes dinamicas Rails com Backbone

var Workspace = Backbone.Router.extend({

routes: { "help": "help", "search/:query": "search", "search/:query/p:page": "search" },

help: function() {},

search: function(query, page) {}

});

#help#search/felix#search/felix/p2

Page 33: Aplicacoes dinamicas Rails com Backbone

var Workspace = Backbone.Router.extend({

routes: { "help": "help", "search/:query": "search", "search/:query/p:page": "search" },

help: function() {},

search: function(query, page) {}

});

#help#search/felix#search/felix/p2

felix 2

Page 34: Aplicacoes dinamicas Rails com Backbone

Backbone.Model

Backbone.Collection

Backbone.Router

Page 35: Aplicacoes dinamicas Rails com Backbone

Backbone.Model

Backbone.Collection

Backbone.RouterBackbone.View

Page 36: Aplicacoes dinamicas Rails com Backbone

var DocumentRow = Backbone.View.extend({

tagName: "li",

className: "document-row",

events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" },

render: function() { ... }

});

Page 37: Aplicacoes dinamicas Rails com Backbone

var DocumentRow = Backbone.View.extend({

tagName: "li",

className: "document-row",

events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" },

render: function() { ... }

});

<li class="document-row"></li>

Page 38: Aplicacoes dinamicas Rails com Backbone

var DocumentRow = Backbone.View.extend({

tagName: "li",

className: "document-row",

events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" },

render: function() { ... }

});

$(".icon").click(open)

Page 39: Aplicacoes dinamicas Rails com Backbone

Exemplo

Page 40: Aplicacoes dinamicas Rails com Backbone
Page 41: Aplicacoes dinamicas Rails com Backbone

layout

Page 42: Aplicacoes dinamicas Rails com Backbone

layoutapplication

Page 43: Aplicacoes dinamicas Rails com Backbone

layoutapplication

ProductView

Page 44: Aplicacoes dinamicas Rails com Backbone

layoutapplication

ProductView

CartView

Page 45: Aplicacoes dinamicas Rails com Backbone
Page 46: Aplicacoes dinamicas Rails com Backbone

click

Page 47: Aplicacoes dinamicas Rails com Backbone

click

Page 48: Aplicacoes dinamicas Rails com Backbone

Passo 1

Page 49: Aplicacoes dinamicas Rails com Backbone

layoutapplication

Page 50: Aplicacoes dinamicas Rails com Backbone

... <div class="container"> <div class="content" id="application"> </div> <footer> <p></p> </footer>

</div>...

app/views/layouts/application.html.erb

Page 51: Aplicacoes dinamicas Rails com Backbone

JavaScript Templates

Page 52: Aplicacoes dinamicas Rails com Backbone

var obj = "bla bla bla";someDiv = document.getElementById("someDiv");someDiv.innerHTML = "<span>" + obj + "</span>";

Page 53: Aplicacoes dinamicas Rails com Backbone

<span> ${obj} </span>

template.jst

Page 54: Aplicacoes dinamicas Rails com Backbone
Page 55: Aplicacoes dinamicas Rails com Backbone

<span> ${obj} </span>

template.jst

Page 56: Aplicacoes dinamicas Rails com Backbone

<span> <%= obj %> </span>

template.jst.ejs

Page 57: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/templates/app.jst.ejs

<div id="products" class="span10"></div><div id="cart" class="span6"></div>

Page 58: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/views/app_view.js

window.AppView = Backbone.View.extend({ template: JST["templates/app"], className: "row", initialize: function(){ }, render: function(){ $(this.el).html(this.template()); return this; }});

Page 59: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/home.js

$(function(){ view = new AppView().render().el; $(view).appendTo("#application");});

Page 60: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/home.js

$(function(){ view = new AppView().render().el; $(view).appendTo("#application");});

<div class="row"> <div id="products" class="span12"> </div> <div id="cart" class="span6"> </div></div>

Page 61: Aplicacoes dinamicas Rails com Backbone

Passo 2

Page 62: Aplicacoes dinamicas Rails com Backbone

ProductView

Page 63: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/templates/product.jst.ejs

<div class="product-image"> <img class="thumbnail" src="http://placehold.it/90x90" alt=""></div><div class="details"> <span class="name"><%= model.get("name") %></span><br /> <span class="price">R$ <%= model.get("price") %></span> <form class="add_product"> <input type="hidden" name="id" value="<%= model.get("id") %>"> <input type="submit" name="commit" value="Comprar" class="btn info"> </form></div>

Page 64: Aplicacoes dinamicas Rails com Backbone

window.ProductView = Backbone.View.extend({ template: JST["templates/product"], className: "product-detail", initialize: function(){ }, render: function(){ $(this.el).html(this.template({model: this.model})); return this; }});

app/assets/javascripts/views/product_view.js

Page 65: Aplicacoes dinamicas Rails com Backbone

rails g model product name:string price:decimal

ActiveRecord::Base.include_root_in_json = false

config/initializers/backbone.rb

rails g controller products

Page 66: Aplicacoes dinamicas Rails com Backbone

rails g model product name:string price:decimal

ActiveRecord::Base.include_root_in_json = false

config/initializers/backbone.rb

rails g controller products

[ {"product": { "name" : "" }}, {"product": { "name": "" }},]

Page 67: Aplicacoes dinamicas Rails com Backbone

rails g model product name:string price:decimal

ActiveRecord::Base.include_root_in_json = false

config/initializers/backbone.rb

rails g controller products

[ {"name" : "" }, {"name": "" },]

Page 68: Aplicacoes dinamicas Rails com Backbone

app/controllers/products_controller.rb

class ProductsController < ApplicationController respond_to :json def index @products = Product.all respond_with @products endend

Page 69: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/models/product.js

window.Product = Backbone.Model.extend({ });

window.ProductsCollection = Backbone.Collections.extend({ model: Product, url: '/products'});

Page 70: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/views/app_view.js

window.AppView = Backbone.View.extend({

initialize: function(){ _.bindAll(this, 'addOne', 'addAll'); this.collection = new ProductsCollection; this.collection.bind('add', this.addOne); this.collection.bind('all', this.addAll); this.collection.fetch(); }, addAll: function(){ $("#products").html(""); this.collection.each(this.addOne); }, addOne: function(product){ view = new ProductView({model: product}).render().el; $(view).appendTo("#products"); }});

Page 71: Aplicacoes dinamicas Rails com Backbone
Page 72: Aplicacoes dinamicas Rails com Backbone

Passo 3

Page 73: Aplicacoes dinamicas Rails com Backbone

CartView

Page 74: Aplicacoes dinamicas Rails com Backbone

<div id="cart-products"></div><hr/>Total: <%= model.get("quantity") %> R$ <%= model.get("total") %>

app/assets/javascripts/templates/cart.jst.ejs

Page 75: Aplicacoes dinamicas Rails com Backbone

window.CartView = Backbone.View.extend({ template: JST["templates/cart"], className: "cart-detail", initialize: function(){ _.bindAll(this, 'render'); this.model.bind('change', this.render); this.model.fetch(); }, render: function(){ $(this.el).html(this.template({model: this.model})); return this; }});

app/assets/javascripts/views/cart_view.js

Page 76: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/models/cart.js

window.Cart = Backbone.Model.extend({ url: function(){ return '/cart'; }});

Page 77: Aplicacoes dinamicas Rails com Backbone

rails g model cart quantity:integer total:decimal

rails g controller cart

Page 78: Aplicacoes dinamicas Rails com Backbone

app/controllers/cart_controller.rb

class CartController < ApplicationController respond_to :json def show @cart ||= Cart.first || Cart.create! respond_with @cart endend

Page 79: Aplicacoes dinamicas Rails com Backbone

app/controllers/cart_controller.rb

class CartController < ApplicationController respond_to :json def show @cart ||= Cart.first || Cart.create! respond_with @cart endend

get 'cart' => "cart#show"

Page 80: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/views/app_view.js

window.AppView = Backbone.View.extend({...

initialize: function(){ ... this.cart = new Cart; this.cartView = new CartView({model: this.cart}). render().el; }, render: function(){ $(this.el).html(this.template()); this.$("#cart").html(this.cartView); return this; }, ...});

Page 81: Aplicacoes dinamicas Rails com Backbone
Page 82: Aplicacoes dinamicas Rails com Backbone

Passo 4

Page 83: Aplicacoes dinamicas Rails com Backbone

click

Page 84: Aplicacoes dinamicas Rails com Backbone

click

Page 85: Aplicacoes dinamicas Rails com Backbone

rails g model cart_product cart:references product:references

Page 86: Aplicacoes dinamicas Rails com Backbone

rails g model cart_product cart:references product:references

app/models/cart.rb

class Cart < ActiveRecord::Base has_many :cart_products has_many :products, through: :cart_products def add_product(product) self.update_attributes quantity: self.quantity + 1, total: total + product.price self.cart_products << CartProduct.new(cart: self, product: product) endend

Page 87: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/models/cart_product.js

window.CartProduct = Backbone.Model.extend({ url: function(){ return "/cart/product/"+this.productId+"/add"; }, initialize: function(args){ this.productId = args.productId; }});

Page 88: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/models/cart_product.js

post 'cart/product/:id/add' => "cart#add_product"

window.CartProduct = Backbone.Model.extend({ url: function(){ return "/cart/product/"+this.productId+"/add"; }, initialize: function(args){ this.productId = args.productId; }});

Page 89: Aplicacoes dinamicas Rails com Backbone

app/controllers/cart_controller.rb

class CartController < ApplicationController respond_to :json def show ... end def add_product @product = Product.find params[:id] @cart = Cart.first @cart.add_product @product respond_with @cart endend

Page 90: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/views/product_view.js

window.ProductView = Backbone.View.extend({ ... events: { "submit form" : "addProductToCart" }, initialize: function(args){ ... this.cart = args.cart }, ... });

Page 91: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/views/product_view.js

window.ProductView = Backbone.View.extend({ ... events: { "submit form" : "addProductToCart" }, initialize: function(args){ ... this.cart = args.cart }, ... });

app/assets/javascripts/views/app_view.js

addOne: function(product){ view = new ProductView({model: product, cart: this.cart}).render().el; $(view).appendTo("#products"); }

Page 92: Aplicacoes dinamicas Rails com Backbone

app/assets/javascripts/views/product_view.js

window.ProductView = Backbone.View.extend({ ... addProductToCart: function(e){ e.preventDefault(); productId = this.$("form.add_product > input[name=id]").val(); item = new CartProduct({productId: productId}); view = this; item.save({}, { success: function(){ view.cart.fetch(); } }); }});

Page 93: Aplicacoes dinamicas Rails com Backbone
Page 94: Aplicacoes dinamicas Rails com Backbone

http://backbone-todos.heroku.com/