Aplicacoes dinamicas Rails com Backbone

  • 1,355 views
Uploaded on

Apresentação na RubyConfBR sob

Apresentação na RubyConfBR sob

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,355
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
10
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Aplicaçõesdinâmicas em Rails
  • 2. Rafael Felix @rs_felixhttp://blog.rollingwithcode.com http://www.crafters.com.br
  • 3. Backbone é uma estrutura paraaplicações que fazem uso pesado de JavaScript, e conecta-se a sua aplicação por uma interface RESTful.
  • 4. Backbone.Model
  • 5. var MyModel = Backbone.Model.extend({})
  • 6. save([attributes],[options])var MyModel = Backbone.Model.extend({})
  • 7. POST PUT save([attributes],[options])var MyModel = Backbone.Model.extend({})
  • 8. save([attributes],[options]) var MyModel = Backbone.Model.extend({})fetch([options])
  • 9. save([attributes],[options]) var MyModel = Backbone.Model.extend({})fetch([options]) setInterval(function(){ model.fetch(); }, 10000);
  • 10. save([attributes],[options]) var MyModel = Backbone.Model.extend({})fetch([options]) validate(attributes)
  • 11. 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 });
  • 12. 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 });
  • 13. Backbone.Model
  • 14. Backbone.ModelBackbone.Collection
  • 15. var Library = Backbone.Collection.extend({ model: Book});
  • 16. add(models, [options]) var Library = Backbone.Collection.extend({ model: Book });
  • 17. add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book });
  • 18. url: /libraryadd(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book });
  • 19. add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book }); fetch([options])
  • 20. add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book }); fetch([options]) Library.fetch() GET /library
  • 21. add(models, [options]) url() var Library = Backbone.Collection.extend({ model: Book }); fetch([options]) create(attributes, [options])
  • 22. var alibrary = new Library;var book = alibrary.create({ title: "A book", author: "Someone"})
  • 23. Backbone.ModelBackbone.Collection
  • 24. Backbone.ModelBackbone.Collection Backbone.Router
  • 25. var Workspace = Backbone.Router.extend({ routes: { "help": "help", "search/:query": "search", "search/:query/p:page": "search" }, help: function() {}, search: function(query, page) {}});
  • 26. 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) {}});
  • 27. 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) {}});
  • 28. 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) {}});
  • 29. 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) {}});
  • 30. Backbone.ModelBackbone.Collection Backbone.Router
  • 31. Backbone.Model Backbone.CollectionBackbone.View Backbone.Router
  • 32. var DocumentRow = Backbone.View.extend({ tagName: "li", className: "document-row", events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" }, render: function() { ... }});
  • 33. 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() { ... }});
  • 34. 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() { ... }});
  • 35. Exemplo
  • 36. layout
  • 37. layout application
  • 38. layout application ProductView
  • 39. layout application ProductView CartView
  • 40. click
  • 41. click
  • 42. Passo 1
  • 43. layout application
  • 44. app/views/layouts/application.html.erb... <div class="container"> <div class="content" id="application"> </div> <footer> <p></p> </footer> </div>...
  • 45. JavaScript Templates
  • 46. var obj = "bla bla bla";someDiv = document.getElementById("someDiv");someDiv.innerHTML = "<span>" + obj + "</span>";
  • 47. template.jst<span> ${obj} </span>
  • 48. template.jst<span> ${obj} </span>
  • 49. template.jst.ejs<span> <%= obj %> </span>
  • 50. app/assets/javascripts/templates/app.jst.ejs <div id="products" class="span10"> </div> <div id="cart" class="span6"> </div>
  • 51. 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; } });
  • 52. app/assets/javascripts/home.js$(function(){ view = new AppView().render().el; $(view).appendTo("#application");});
  • 53. 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>
  • 54. Passo 2
  • 55. ProductView
  • 56. 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>
  • 57. 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; }});
  • 58. rails g model product name:string price:decimal rails g controller products config/initializers/backbone.rb ActiveRecord::Base.include_root_in_json = false
  • 59. 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": "" }}, ]
  • 60. 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": "" }, ]
  • 61. app/controllers/products_controller.rbclass ProductsController < ApplicationController respond_to :json def index @products = Product.all respond_with @products endend
  • 62. app/assets/javascripts/models/product.jswindow.Product = Backbone.Model.extend({});window.ProductsCollection = Backbone.Collections.extend({ model: Product, url: /products});
  • 63. 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"); }});
  • 64. Passo 3
  • 65. CartView
  • 66. app/assets/javascripts/templates/cart.jst.ejs<div id="cart-products"></div><hr/>Total: <%= model.get("quantity") %> R$ <%= model.get("total") %>
  • 67. 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; }});
  • 68. app/assets/javascripts/models/cart.js window.Cart = Backbone.Model.extend({ url: function(){ return /cart; } });
  • 69. rails g model cart quantity:integer total:decimal rails g controller cart
  • 70. app/controllers/cart_controller.rbclass CartController < ApplicationController respond_to :json def show @cart ||= Cart.first || Cart.create! respond_with @cart endend
  • 71. 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
  • 72. 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; }, ...});
  • 73. Passo 4
  • 74. click
  • 75. click
  • 76. rails g model cart_product cart:references product:references
  • 77. 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
  • 78. 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; }});
  • 79. 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"
  • 80. 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
  • 81. app/assets/javascripts/views/product_view.js window.ProductView = Backbone.View.extend({ ... events: { "submit form" : "addProductToCart" }, initialize: function(args){ ... this.cart = args.cart }, ... });
  • 82. 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");}
  • 83. 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(); } }); }});
  • 84. http://backbone-todos.heroku.com/
  • 85. 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