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》是一本经典的Rails开发指南,中文版的出版使得更多的中国开发者能够深入理解并应用敏捷开发方法与Ruby on Rails框架。这本书是Rails开发者的必备参考资料,它详细介绍了如何...
《Agile Web Development with Rails》(敏捷Web开发:Ruby on Rails)这本书,作为Rails开发新手的教材,强调了敏捷开发方法,并以其帮助开发者建立起一个实用的Web应用。从给出的文件信息来看,这本书正在编写过程...
本书旨在帮助开发者充分利用Rails 4的特性,提高开发效率,实现快速迭代和高质量的代码编写。 Rails是一个强大的、基于模型-视图-控制器(MVC)架构模式的开源Web应用框架,它以Ruby编程语言为基础,强调简洁和生产力...
#### 4. ActionPack:视图和控制器的支持 ActionPack是Rails框架中的另一个关键组件,它包含了处理HTTP请求和响应的所有工具,以及生成HTML视图的模板引擎。ActionPack使得开发者能够轻松地创建和管理Web页面,实现...
此外,第二版还深入讨论了Rails 3.x和4.x中的路由系统,以及如何使用Unobtrusive JavaScript(UJS)实现更干净、分离的前端代码。 这两本书都强调了敏捷开发的原则,如迭代开发、持续集成、用户故事和重构。它们...
《Agile Web Development with Rails, 4th Edition》是一本专为希望利用Rails框架进行敏捷Web开发的开发者们设计的专业指南。本书深入浅出地介绍了Rails的核心概念、实践方法及应用场景,并通过丰富的示例来帮助读者...
《敏捷Web开发与Rails》第四版是一本专为软件开发者设计的权威指南,全面涵盖了使用Ruby on Rails框架进行敏捷Web应用开发的知识。Rails 3是该版本的重点,它引入了许多新特性和改进,使得开发过程更为高效且灵活。...
### 敏捷Web开发与Rails 3:关键知识点解析 #### 一、Rails版本与兼容性 本书《敏捷Web开发与Rails》第三版是基于Rails 2编写的。截至本书印刷时,当前可用的Rails Gem版本为2.1。书中所包含的所有代码均已在该...
### 敏捷Web开发与Rails 4版:Rails 3.1版本的关键知识点解析 #### 一、前言 《敏捷Web开发与Rails》第四版是面向Ruby on Rails框架的一本经典著作,由Sam Ruby、Dave Thomas、David Heinemeier Hansson等多位专家...
### Agile Web Development with Rails 第四版 #### 书籍概述 《Agile Web Development with Rails》第四版是一本针对Ruby on Rails框架的经典教程书籍。本书由Sam Ruby、Dave Thomas、David Heinemeier Hansson等...
Agile Web Development with Rails 4th(正式版).pdf
### Agile Web Development with Rails for Rails 3.2 #### 核心知识点概览 - **Rails 3.2概述** - **敏捷开发方法论** - **Model-View-Controller (MVC) 模式** - **Ruby on Rails基础与高级特性** - **面向对象...
agile web development with rails 5(英文电子书).............................................................................................................................................................