appointment: this demo ran in ubuntu, and Rails 2.2.2
the demo comes from agile web development with rails 3
script>>some linux script
mysql>some db command
---------------------------------------------------------
Add a Dash of Ajax
---------------------------------------------------------
step 1
u can think of rails partial templates as a kind of method for views.
a partial is simply a chunk of view in its own separate file. u can invoke(render)
a partial from another template or from a controller, and the partial will render
itself and return the result of that rendering
views/store/add_to_cart.html.erb
<%= render(:partial => "cart_item" , :collection => @cart.items) %>
views/store/_cart_item.html.erb
views/store/_cart.html.erb
<%= render(:partial => "cart_item" , :collection => cart.items) %>
views/layouts/store.html.erb
<div id="cart">
<%= render(:partial => "cart" , :object => @cart) %>
</div>
Coding list like this
depot_j/app/views/store/add_to_cart.html.erb
<div class="cart-title">Your Cart</div>
<table>
<%= render(:partial => "cart_item" , :collection => @cart.items) %>
<tr class="total-line">
<td colspan="2">Total</td>
<td class="total-cell"><%= number_to_currency(@cart.total_price) %></td>
</tr>
</table>
<%= button_to "Empty cart" , :action => :empty_cart %>
app/views/store/_cart_item.html.erb
<tr>
<td><%= cart_item.quantity %>×</td>
<td><%=h cart_item.title %></td>
<td class="item-price"><%= number_to_currency(cart_item.price) %></td>
</tr>
app/views/store/_cart.html.erb
<div class="cart-title">Your Cart</div>
<table>
<%= render(:partial => "cart_item" , :collection => cart.items) %>
<tr class="total-line">
<td colspan="2">Total</td>
<td class="total-cell"><%= number_to_currency(cart.total_price) %></td>
</tr>
</table>
<%= button_to "Empty cart" , :action => :empty_cart %>
app/views/layouts/store.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html>
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "depot" , :media => "all" %>
</head>
<body id="store">
<div id="banner">
<%= image_tag("logo.png" ) %>
<%= @page_title || "Pragmatic Bookshelf" %>
</div>
<div id="columns">
<div id="side">
<div id="cart">
<%= render(:partial => "cart" , :object => @cart) %>
</div>
<a href="http://www....">Home</a><br />
<a href="http://www..../faq">Questions</a><br />
<a href="http://www..../news">News</a><br />
<a href="http://www..../contact">Contact</a><br />
</div>
<div id="main">
<% if flash[:notice] -%>
<div id="notice"><%= flash[:notice] %></div>
<% end -%>
<%= yield :layout %>
</div>
</div>
</body>
</html>
We’re invoking the layout while looking at the store’s index action, and that action doesn't currently set @cart. That’s easy enough to remedy:
app/controllers/store_controller.rb
def index
@products = Product.find_products_for_sale
@cart = find_cart
end
redirect the browser back to the index:
app/controllers/store_controller.rb
def add_to_cart
product = Product.find(params[:id])
@cart = find_cart
@cart.add_product(product)
redirect_to_index
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}" )
redirect_to_index("Invalid product" )
end
app/controllers/store_controller.rb
def redirect_to_index(msg = nil)
flash[:notice] = msg if msg
redirect_to :action => 'index'
end
add two method in models/cart.rb
def total_price
@items.sum { |item| item.price }
end
def total_items
@items.sum { |item| item.quantity }
end
step 2
create an ajax-based cart
1. use form_remote_tag to create a remote procedure call to ur application.
chang>> views/store/index.html.erb
<%= button_to "Add to Cart" , :action => :add_to_cart, :id => product %>
to >>
<% form_remote_tag :url => { :action => 'add_to_cart', :id => product } do %>
<%= submit_tag "Add to Cart" %>
<% end %>
2. add a call to javascript_inlude_tag to the <head> section of the store layout:
views/layouts/store.html.erb
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag "depot" , :media => "all" %>
<%= javascript_include_tag :defaults %>
</head>
3. change response to the controllers to add_to_cart
def add_to_cart
product = Product.find(params[:id])
@cart = find_cart
@cart.add_product(product)
respond_to do |format|
format.js
end
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}" )
redirect_to_index("Invalid product" )
end
4. rails supports RJS templates-- the JS stands for JavaScript. A .js.rjs template is a way of getting JavaScript on the browser to do what you want, all by writing server-side ruby code. Let's write our first: add_to_cart.js.rjs
.
app/views/store/add_to_cart.js.rjs
page.replace_html("cart" , :partial => "cart" , :object => @cart)
5. u mey need to delete the old add_to_cart.html.erb
step 3 hight-lighting changes
1. we need to know if the current_item changed.
/models/cart.rb
def add_product(product)
current_item = @items.find {|item| item.product == product}
if current_item
current_item.increment_quantity
else
current_item = CartItem.new(product)
@items << current_item
end
current_item
end
2. add controller response
/controllers/store_controller.rb
def add_to_cart
product = Product.find(params[:id])
logger.error( product);
@cart = find_cart
@current_item = @cart.add_product(product)
respond_to do |format|
format.js
end
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid product #{params[:id]}" )
redirect_to_index( "Invalid product" )
end
3. identify changed current_item
<% if cart_item == @current_item %>
<tr id="current_item">
<% else %>
<tr>
<% end %>
<td><%= cart_item.quantity %>×</td>
<td><%=h cart_item.title %></td>
<td class="item-price"><%= number_to_currency(cart_item.price) %></td>
</tr>
4. add effect of the dynamic change content
views/store/add_to_cart.js.rjs
page.replace_html("cart" , :partial => "cart" , :object => @cart)
page[:current_item].visual_effect :highlight,
:startcolor => "#88ff88"
step 3
hiding an Empty Cart. and this may redirect the page
<% unless cart.items.empty? %>
<div class="cart-title" >Your Cart</div>
<table>
<%= render(:partial => "cart_item" , :collection => cart.items) %>
<tr class="total-line" >
<td colspan="2" >Total</td>
<td class="total-cell" ><%= number_to_currency(cart.total_price) %></td>
</tr>
</table>
<%= button_to "Empty cart" , :action => :empty_cart %>
<% end %>
step 4
the ajax way
app/models/cart.rb
def total_items
@items.sum { |item| item.quantity }
end
layout
<div id="cart"
<% if @cart.items.empty? %>
style="display: none"
<% end %>
>
<%= render(:partial => "cart" , :object => @cart) %>
</div>
----------------------------------------------------
views/store/add_to_cart.js.rjs
page.replace_html("cart" , :partial => "cart" , :object => @cart)
page[:cart].visual_effect :blind_down if @cart.total_items == 1
step 5
use Helper Method
for this view is not looks good, we can use helper method to divide some parts
<div id="cart"
<% if @cart.items.empty? %>
style="display: none"
<% end %>
>
<%= render(:partial => "cart" , :object => @cart) %>
</div>
/app/views/layouts/store.html.erb
<% hidden_div_if(@cart.items.empty?, :id => "cart" ) do %>
<%= render(:partial => "cart" , :object => @cart) %>
<% end %>
app/helpers/store_helper.rb
module StoreHelper
def hidden_div_if(condition, attributes = {}, &block)
if condition
attributes["style" ] = "display: none"
end
content_tag("div" , attributes, &block)
end
end
分享到:
相关推荐
Ruby on Rails helps you produce high-quality, beautiful-looking web applications quickly. You concentrate on creating the application, and Rails takes care of the details., Tens of thousands of ...
Agile Web Development with Rails 5 英文无水印原版pdf pdf所有页面使用FoxitReader、PDF-XChangeViewer、SumatraPDF和Firefox测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书...
Agile Web Development with Rails
最新版的agile rails开发,经典!for rails 1.2.1
Agile Web Development with Rails (PDF)
Agile Web Development with Rails, 4th Edition, Rails 3.1
Agile Web Development with Rails 3nd Edition beta
Agile Web Development with Rails (4th edition).pdf
Agile Web Development with Rails, 4th Edition
Agile Web Development with Rails (4th edition) rails入门必读的一本.英文.最新的第四版 for rails 3.03 Beta版
博文链接:https://jbf034.iteye.com/blog/219935
Pragmatic - Agile Web Development with Rails 2ndPragmatic - Agile Web Development with Rails 2ndPragmatic - Agile Web Development with Rails 2ndPragmatic - Agile Web Development with Rails 2...
正式版 已经上传, 请到下面链接下载 http://download.csdn.net/source/3432550
ruby rails agile 中文教程