Aplicacoes dinamicas Rails com Backbone
Upcoming SlideShare
Loading in...5
×
 

Aplicacoes dinamicas Rails com Backbone

on

  • 1,634 views

Apresentação na RubyConfBR sob

Apresentação na RubyConfBR sob

Statistics

Views

Total Views
1,634
Views on SlideShare
1,620
Embed Views
14

Actions

Likes
2
Downloads
10
Comments
0

2 Embeds 14

http://coderwall.com 13
http://www.hanrss.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Aplicacoes dinamicas Rails com Backbone Aplicacoes dinamicas Rails com Backbone Presentation Transcript

  • Aplicaçõesdinâmicas em Rails
  • Rafael Felix @rs_felixhttp://blog.rollingwithcode.com http://www.crafters.com.br
  • Backbone é uma estrutura paraaplicações que fazem uso pesado de JavaScript, e conecta-se a sua aplicação por uma interface RESTful. View slide
  • Backbone.Model View slide
  • var MyModel = Backbone.Model.extend({})
  • save([attributes],[options])var MyModel = Backbone.Model.extend({})
  • POST PUT save([attributes],[options])var MyModel = Backbone.Model.extend({})
  • save([attributes],[options]) var MyModel = Backbone.Model.extend({})fetch([options])
  • save([attributes],[options]) var MyModel = Backbone.Model.extend({})fetch([options]) setInterval(function(){ model.fetch(); }, 10000);
  • save([attributes],[options]) var MyModel = Backbone.Model.extend({})fetch([options]) validate(attributes)
  • var Chapter = Backbone.Model.extend({ validate: function(attrs) { if (attrs.end < attrs.start) { return "cant 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 });
  • var Chapter = Backbone.Model.extend({ validate: function(attrs) { if (attrs.end < attrs.start) { return "cant 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 });
  • Backbone.Model
  • Backbone.ModelBackbone.Collection
  • var Library = Backbone.Collection.extend({ model: Book});
  • add(models, [options]) var Library = Backbone.Collection.extend({ model: Book });
  • add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book });
  • url: /libraryadd(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book });
  • add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book }); fetch([options])
  • add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book }); fetch([options]) Library.fetch() GET /library
  • add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book }); fetch([options]) create(attributes, [options])
  • var alibrary = new Library;var book = alibrary.create({ title: "A book", author: "Someone"})
  • Backbone.ModelBackbone.Collection
  • Backbone.ModelBackbone.Collection Backbone.Router
  • var Workspace = Backbone.Router.extend({ routes: { "help": "help", "search/:query": "search", "search/:query/p:page": "search" }, help: function() {}, search: function(query, page) {}});
  • var Workspace = Backbone.Router.extend({ routes: { "help": "help", #help "search/:query": "search", #search/felix "search/:query/p:page": "search" #search/felix/p2 }, help: function() {}, search: function(query, page) {}});
  • var Workspace = Backbone.Router.extend({ routes: { "help": "help", #help "search/:query": "search", #search/felix "search/:query/p:page": "search" #search/felix/p2 }, help: function() {}, search: function(query, page) {}});
  • var Workspace = Backbone.Router.extend({ routes: { "help": "help", #help "search/:query": "search", #search/felix "search/:query/p:page": "search" #search/felix/p2 }, help: function() {}, search: function(query, page) {}});
  • var Workspace = Backbone.Router.extend({ routes: { "help": "help", #help "search/:query": "search", #search/felix "search/:query/p:page": "search" #search/felix/p2 }, help: function() {}, felix 2 search: function(query, page) {}});
  • Backbone.ModelBackbone.Collection Backbone.Router
  • Backbone.Model Backbone.CollectionBackbone.View Backbone.Router
  • var DocumentRow = Backbone.View.extend({ tagName: "li", className: "document-row", events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" }, render: function() { ... }});
  • var DocumentRow = Backbone.View.extend({ tagName: "li", <li class="document-row"></li> className: "document-row", events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" }, render: function() { ... }});
  • var DocumentRow = Backbone.View.extend({ tagName: "li", className: "document-row", events: { "click .icon": "open", $(".icon").click(open) "click .button.edit": "openEditDialog", "click .button.delete": "destroy" }, render: function() { ... }});
  • Exemplo
  • layout
  • layout application
  • layout application ProductView
  • layout application ProductView CartView
  • click
  • click
  • Passo 1
  • layout application
  • app/views/layouts/application.html.erb... <div class="container"> <div class="content" id="application"> </div> <footer> <p></p> </footer> </div>...
  • JavaScript Templates
  • var obj = "bla bla bla";someDiv = document.getElementById("someDiv");someDiv.innerHTML = "<span>" + obj + "</span>";
  • template.jst<span> ${obj} </span>
  • template.jst<span> ${obj} </span>
  • template.jst.ejs<span> <%= obj %> </span>
  • app/assets/javascripts/templates/app.jst.ejs <div id="products" class="span10"> </div> <div id="cart" class="span6"> </div>
  • 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; } });
  • app/assets/javascripts/home.js$(function(){ view = new AppView().render().el; $(view).appendTo("#application");});
  • 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>
  • Passo 2
  • ProductView
  • 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>
  • app/assets/javascripts/views/product_view.jswindow.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; }});
  • rails g model product name:string price:decimal rails g controller products config/initializers/backbone.rb ActiveRecord::Base.include_root_in_json = false
  • rails g model product name:string price:decimal rails g controller products config/initializers/backbone.rb ActiveRecord::Base.include_root_in_json = false [ {"product": { "name" : "" }}, {"product": { "name": "" }}, ]
  • rails g model product name:string price:decimal rails g controller products config/initializers/backbone.rb ActiveRecord::Base.include_root_in_json = false [ {"name" : "" }, {"name": "" }, ]
  • app/controllers/products_controller.rbclass ProductsController < ApplicationController respond_to :json def index @products = Product.all respond_with @products endend
  • app/assets/javascripts/models/product.jswindow.Product = Backbone.Model.extend({});window.ProductsCollection = Backbone.Collections.extend({ model: Product, url: /products});
  • app/assets/javascripts/views/app_view.jswindow.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"); }});
  • Passo 3
  • CartView
  • app/assets/javascripts/templates/cart.jst.ejs<div id="cart-products"></div><hr/>Total: <%= model.get("quantity") %> R$ <%= model.get("total") %>
  • app/assets/javascripts/views/cart_view.jswindow.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/models/cart.js window.Cart = Backbone.Model.extend({ url: function(){ return /cart; } });
  • rails g model cart quantity:integer total:decimal rails g controller cart
  • app/controllers/cart_controller.rbclass CartController < ApplicationController respond_to :json def show @cart ||= Cart.first || Cart.create! respond_with @cart endend
  • app/controllers/cart_controller.rb get cart => "cart#show"class CartController < ApplicationController respond_to :json def show @cart ||= Cart.first || Cart.create! respond_with @cart endend
  • app/assets/javascripts/views/app_view.jswindow.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; }, ...});
  • Passo 4
  • click
  • click
  • rails g model cart_product cart:references product:references
  • 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) end end
  • app/assets/javascripts/models/cart_product.jswindow.CartProduct = Backbone.Model.extend({ url: function(){ return "/cart/product/"+this.productId+"/add"; }, initialize: function(args){ this.productId = args.productId; }});
  • app/assets/javascripts/models/cart_product.jswindow.CartProduct = Backbone.Model.extend({ url: function(){ return "/cart/product/"+this.productId+"/add"; }, initialize: function(args){ this.productId = args.productId; }}); post cart/product/:id/add => "cart#add_product"
  • app/controllers/cart_controller.rbclass 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
  • 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/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");}
  • app/assets/javascripts/views/product_view.jswindow.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(); } }); }});
  • http://backbone-todos.heroku.com/
  • Obrigado felix.rafael@gmail.com http://twitter.com/rs_felix http://github.com/fellix Links http://documentcloud.github.com/backbone/ https://github.com/creationix/haml-js https://github.com/codebrew/backbone-railshttp://seesparkbox.com/foundry/better_rails_apis_with_rabl