拖动效果
介绍下辅助方法吧!
通过ScriptaculousHelper模块的帮助,允许我们在页面中通过拖动来实现Ajax交互。Rails用以实现拖动效果主要有如下两个方法。
● draggable_element:该方法将某个HTML元素定义成一个可以拖动的元素。
● drop_receiving_element:该方法将某个HTML元素定义成一个拖动目的地元素。将一个可拖动元素(使用draggable_element定义)拖动到拖动目的地元素(使用drop_receiving_element定义)时,Rails将会向服务器发送Ajax请求。
记住
<%= javascript_include_tag "prototype","dragdrop"%>
dragdrop.JS必须的
拖动示例
<%= image_tag("vista.jpg" , :id =>"image1")%> <%= image_tag("vista.jpg" , :id =>"image2")%> <%= draggable_element("image1", :revert => true)%> <%= draggable_element("image2", :revert => false)%>
使用drop_receiving_element方法的语法格式如下:
drop_receiving_element (element_id, options = {})
该方法将element_id所指定的HTML元素定义成一个可拖动的目的地。因为该方法会发送Ajax选项,因此可以接受如下几个选项。
● :url:该选项指定一个符合url_for格式的URL地址。
● :update:该选项指定使用服务器响应来更新哪个HTML元素。
除此之外,当然也可指定:complete、:loaded等Ajax交互阶段的特定选项。
下面将使用draggable_element和drop_receiving_element实现一个购物车效果。
进入购物车页面时,先经过如下Action处理,该Action创建了一个字符串数组作为实例变量。
# 定义进入购物车的Action
def cart # 如果session[:cart]为nil,则将其赋为{},否则不改变 session[:cart] ||= {} # 创建一个字符串数组 @books = %w{spring ajax struts2} end在上面的Action中定义了用户的:cart Session,该Session用以跟踪用户的购物状态。还手动构建了一个字符串数组,这个字符串数组将作为系统的商品。
提示 实际应用中我们可以通过Model从数据库中取出所有商品,但本应用为了简化应用的复杂度,只突出Ajax应用,故没有使用Model进行持久化访问。
视图页面将使用draggable_element方法和drop_receiving_element方法来构建通过拖动来购买商品的应用。cart.rhtml页面的代码如下:
上面页面会迭代输出@books实例变量中每个元素,并将每个元素都转换成一个可拖动的元素;除此之外,还使用drop_receiving_element方法定义了一个拖动目的地元素,每当元素被拖动到该元素时,Rails将向add Action发送请求,并发送被拖动元素的id作为请求参数。拖动效果
下面是所有商品
<[email=%@books.each]%@books.each[/email] do |book|%> <%= image_tag book + ".jpg", :id =>book %> <%= draggable_element(book, :revert => true)%> <%end%>将上面商品拖到下面方框中就是购买了该商品
<%= drop_receiving_element("my_cart", :url => {:action => "add" }, :update=>"my_cart") %>
下面是add Action的代码:
# 定义添加物品的Action
def add # 取得请求参数 product_id = params[:id]; # 如果请求参数不为空 if product_id != nil then # 如果购物车中的物品已经存在,则数量加1,否则设置该物品数量为1 session[:cart][product_id] = session[:cart].include?(product_id) ? session[:cart][product_id] + 1 : 1 end # 使用_cart.rhtml页面来生成响应 render :partial => 'cart' end从上面的Action代码来看,Rails拖动时会将被拖动元素的id作为请求参数发送到服务器,上面的Action就可以获取用户希望购买的物品,从而可以修改用户的session状态。该Action最后提交到_cart.rhtml页面来显示处理结果。该页面的代码如下:
<% session[:cart].each do |product,quantity| %><% quantity.times do |i| %> <%= image_tag product + ".jpg", :id => "item_#{product}_#{i}", :size => "40x60", :style => "position:relative;" %> <% end %> <%= product %>:<%= quantity %><;% end %>
<%= "您暂时还未购买任何图书!" if session[:cart].empty? %>
上面的_cart.rhtml页面生成的响应将会用来更新原来页面的my_cart元素,从而可以通过拖动来购买商品
上面应用的界面更加友好:浏览者可以直接通过拖动鼠标来购买商品,这是很有乐趣的事情。
值得指出的,如果希望加载该页面时即显示用户的购物车中有多少商品,应该在用户进入该页面时立即向add Action发送请求(add Action已经处理了没有请求参数的情形)。上面应用已经实现了该功能,我们在body元素load时通过remote_function来发送请求,从而实现了页面加载时立即发送请求的要求。