Ruby on Rails实战–创建一个网上商店C小试Ajax

上一节:Ruby on Rails实战–创建一个网上商店B前台

本节将向商店加入一个Ajax购物篮,使商店产品列表在不刷新的情况下更新显示购物篮信息

修改depot/app/controllers/store_controller.rb文件,如下:
  def index
    @products = Product.find_products_for_sale
    @cart = find_cart #加入对@cart的定义
  end
   def add_to_cart
    begin
      @product = Product.find(params[:id])
    rescue
      logger.error("Attempt to access invalid product #{params[:id]}")
      redirect_to_index("Invalid product")
    else

      @cart = find_cart
      @current_item = @cart.add_product(@product)
      redirect_to_index unless request.xhr?
   #request.xhr判断是否xmlHttpRequest, 否将指向index action, 用来兼容关闭了javascript功能的浏览器
   #开发时以无Ajax的为蓝本,再修改到ajax,以方便兼容性处理
    end
  end
  #….
  private
  def redirect_to_index(msg = nil)
#msg = nil 指定msg的默认值, 如果msg没有说明, msg = nil.
    flash[:notice] = msg if msg
 #加入对无参数的支持
    redirect_to :action => :index
  end
  #…

修改depot/app/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

修改depot/app/controllers/store_controller.rb文件,如下:
def add_to_cart
 begin
  @product = Product.find(params[:id])
 rescue
  logger.error("Attempt to access invalid product #{params[:id]}")
  redirect_to_index("Invalid product")
 else
  @cart = find_cart
  @current_item = @cart.add_product(@product) #新加,定义@current_item
 end
end
#….
  def empty_cart
    session[:cart] = nil
    redirect_to_index #清空购物篮后返回商品列表
  end
#…

修改depot/app/models/cart.rb文件,增加一个购物篮内商品数据变量
def total_items
 @items.inject(0) {|sum, item| sum + item.quantity}
end

在depot/app/views/store/index.rhtml
中将:
 <%= button_to "Add to Cart", :action => :add_to_cart, :id => product %>
改为:
  <%= form_remote_tag :url => { :action => :add_to_cart, :id => product } %>
        <%= submit_tag "Add to Cart" %>
        <%= end_form_tag %>
 
在depot/app/views/layouts/store.rhtml文件里加入模板对javascript的支持,如下:
<html>
 <head>
  <title>Pragprog Books Online Store</title>
  <%= stylesheet_link_tag "depot", :media => "all" %>
  <%= javascript_include_tag :defaults %>
 </head>

在depot/app/views/store/新加一个partial template _cart.rhtml,内容如下:
<div class="cart-title">Your Cart</div>
<table>
 <%= render(:partial => "cart_item", :collection => cart.items) %>
 <!–调用另一个partial template _cart_item.rhtml–>
 <tr class="total-line">
  <td colspan="2">Total</td>
  <td class="total-cell"><%= format_price(cart.total_price) %></td>
 </tr>
</table>
<%= button_to "Empty cart", :action => :empty_cart %>
partial template以下找线开头,由render的调用.

在depot/app/views/store/新加一个partial template _cart_item.rhtml,内容如下:
<% if cart_item == @current_item %>
<!–后面用来显示特殊效果–>
 <tr id="current_item">
 <% else %>
 <tr>
<% end %>
  <td><%= cart_item.quantity %>&times;</td>
  <td><%= h(cart_item.title) %></td>
  <td class="item-price"><%= format_price(cart_item.price) %></td>
 </tr>

在depot/app/views/layouts/store.rhtml文件中增加调用partial template的代码:
   <div id="side">
                <%= hidden_div_if(@cart.items.empty?, :id => "cart") %>
    <!–hidden_div_if 这个 helpper method用来向div加入display:none属性, 代码见下文–>
                    <%= render(:partial =>"cart", :object => @cart) %>
                </div>
    …..

创建hidden_div_if  helpper method
  def hidden_div_if(condition, attributes = {})
    if condition
      attributes["style"] = "display: none"
    end
    attrs = tag_options(attributes.stringify_keys)
    "<div #{attrs}>"
  end

删除不用了的add_to_cart.rhtml

新建depot/app/views/store/add_to_cart.rjs文件,内容如下:
page[:cart].replace_html :partial => ‘cart’, :object => @cart
#将页面中id=cart的元素换成partial _cart.rhtml的内容
page[:cart].visual_effect :blind_down if @cart.total_items == 1
#当向购物篮添加第一个商品时,特效显示出购物篮
page[:current_item].visual_effect :highlight,
               :startcolor =>"#88ff88",
               :endcolor =>"#114411"
#当购物篮商品发生变化时,特效显示变化行

本节完成,为使ajax效果生效, 我重新启动了服务器

下一节:Ruby on Rails实战–创建一个网上商店D收银台

本文最后更新 20070108

转载请注明: 转自船长日志, 本文链接地址: http://www.cslog.cn/Content/ruby_on_rails_ajax_eshop/

此条目发表在 Ruby on Rails 分类目录。将固定链接加入收藏夹。

发表评论