源文檔在下面的URL:
https://github.com/kamionayuki/shop
用非AJAX的方式實(shí)現(xiàn)了查詢和排序后滓走,還是想用AJAX的方式實(shí)現(xiàn)。但在此之前总放,需要把cookies這個(gè)隱患排除掉蛤虐。無意中有了一個(gè)驚人的發(fā)現(xiàn)获印,就是在views中xxx_path是可以隨意加參數(shù)的。比如:
view中
<%= link_to "all products", products_path(para1: "txy", para2: " ai ", para3: "txl") %>
controller中
def index
@para = params[:para1] +params[:para2] + params[:para2]
@product = Product.all
end
用這個(gè)方法完全可以繞過cookies胆建,以免把相關(guān)信息暴露出去躬贡。真的是太好了。
去掉了cookies后眼坏,就想用ajax來進(jìn)行查詢和排序,原理跟原來一樣酸些,只是用了ajax的方法了宰译,具體操作如下:
- views中
修改index.html.erb
<h1><%= link_to "Product", root_path %></h1>
<%= will_paginate @products, renderer: BootstrapPagination::Rails %>
<%= form_tag search_products_path, method: "get", remote: true do %>
<%= label_tag :s_price, "Price" %>
<%= text_field_tag :s_price %>
<%= submit_tag "Search" %>
<% end %>
<table class="table table-striped">
<%= render partial: 'thead', locals: {query: @query, order: @order} %>
<%= render 'tbody' %>
</table>
新增加"views/products/_thead.html.erb",并且用params[:query]來傳送當(dāng)前頁面的查詢條件
<thead>
<tr>
<th><%= link_to "ID", sort_products_path(sort_by: order[:p_id], query: query), remote: true %></th>
<th><%= link_to "Name", sort_products_path(sort_by: order[:p_name], query: query), remote: true %></th>
<th><%= link_to "Price", sort_products_path(sort_by: order[:p_price], query: query), remote: true %></th>
<th><%= link_to "Description", sort_products_path(sort_by: @order[:p_description], query: @query), remote: true %></th>
<th><%=t '.actions', :default => t("helpers.actions") %></th>
</tr>
</thead>
新增加"views/products/_tbody.html.erb"
<tbody>
<% @products.each do |product| %>
<tr>
<td><%= link_to product.id, product_path(product) %></td>
<td><%= product.name %></td>
<td><%= product.price %></td>
<td><%= product.description %></td>
<td>
<%= link_to t('.edit', :default => t("helpers.links.edit")),
edit_product_path(product), :class => 'btn btn-default btn-xs' %>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
product_path(product),
:method => :delete,
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-xs btn-danger' %>
</td>
</tr>
<% end %>
</tbody>
新增加"views/products/_products.js.erb"
$("thead").next().remove();
$("thead").after("<%= j render('tbody') %>");
$("tbody").prev().remove();
$("tbody").before("<%= j render(partial: 'thead', locals: {query: @query, order: @order}) %>");
- controller中沒有多少變化,只是把cookies[:query]變成了params[:query]魄懂,同時(shí)增加了@query用來把查詢條件傳給頁面中的params[:query]沿侈。并且對(duì)@order進(jìn)行了一下優(yōu)化。
def index
@products = Product.all.paginate(page: params[:page], per_page: 12)
query = "1 = 1"
@query = encode(query)
respond_to do |format|
format.html
end
end
def sort
@query = params[:query]
query = decode(params[:query])
order_query = params[:sort_by].join(" ")
@products = Product.where(query).order(order_query).paginate(page: params[:page], per_page: 12)
order_change(@order, params[:sort_by])
render '_products'
end
def search
if params[:s_price] == ""
redirect_to :back
else
query = "price like \'%s\'" % params[:s_price]
@products = Product.where(query).paginate(page: params[:page], per_page: 12)
@query = encode(query)
render '_products'
end
end
private
def order_init
@order = {}
@order[:p_price] = ["price", "desc"]
@order[:p_id] = ["id", "desc"]
@order[:p_name] = ["name", "desc"]
@order[:p_description] = ["description", "desc"]
return @order
end
def order_change(order, sort_by)
key = "p_" + sort_by.first
value = sort_by.last
value = value == "desc" ? "asc" : "desc"
order[key.to_sym] = [sort_by.first, value]
end
- routs中
resources :products do
collection do
get 'search'
get 'sort'
end
end
大功告成J欣酢W菏谩!
wait~~~用ajax來實(shí)現(xiàn)查詢和排序的好處是頁面的url地址不會(huì)把相關(guān)信息顯示出來填帽。但上面的做法有兩個(gè)問題
- 因?yàn)橛玫氖恰癵et”方法蛛淋,所以當(dāng)鼠標(biāo)移動(dòng)在表頭的鏈接上時(shí),仍然會(huì)顯示相關(guān)信息(這個(gè)應(yīng)該好處理,只要把sort改成post篡腌,views用button_to就可以了褐荷,具體如下)
view中
<thead>
<tr>
<th><%= button_to "ID", sort_products_path(sort_by: order[:p_id], query: query), remote: true, class: "btn btn_link" %></th>
<th><%= button_to "Name", sort_products_path(sort_by: order[:p_name], query: query), remote: true, class: "btn btn_link" %></th>
<th><%= button_to "Price", sort_products_path(sort_by: order[:p_price], query: query), remote: true, class: "btn btn_link" %></th>
<th><%= button_to "Description", sort_products_path(sort_by: @order[:p_description], query: @query),
remote: true, class: "btn btn_link" %></th>
<th><%=t '.actions', :default => t("helpers.actions") %></th>
</tr>
</thead>
routes中
resources :products do
collection do
get 'search'
post 'sort'
end
end
- 用了ajax進(jìn)行排序和查詢后。從此再也不能用will_paginate進(jìn)行分頁了嘹悼。為這解決這個(gè)叛甫,花了兩個(gè)多小時(shí)也沒有搞定,也沒有查到資料杨伙。不知道有沒有好的方法來進(jìn)行處理其监。參考了一下其它的網(wǎng)站,如果是ajax進(jìn)行查詢的排序的話限匣,就沒有分頁功能抖苦。如果有分頁功能的話,就沒有用到ajax膛腐。因此以后如果有分頁的需求睛约,就不用ajax好了。吼吼~~~~
繼續(xù)補(bǔ)充(重要)
可以對(duì)will_paginate進(jìn)行ajax的分頁了U苌怼辩涝!真的是無心插柳啊,哈哈哈哈勘天。如下:
- index.html.erb修改一下:
<%- model_class = Product -%>
<h1><%= link_to "Product", root_path %></h1>
<%= render 'paginate' %>
<%= form_tag search_products_path, method: "get", remote: true do %>
<%= label_tag :s_price, "Price" %>
<%= text_field_tag :s_price %>
<%= submit_tag "Search" %>
<% end %>
<table class="table table-striped">
<%= render partial: 'thead', locals: {query: @query, order: @order} %>
<%= render 'tbody' %>
</table>
- 增加一個(gè)_paginate.html.erb的文件
<%= will_paginate @products, renderer: BootstrapPagination::Rails %>
- _products.js.erb修改一下:
$("thead").next().remove();
$("thead").after("<%= j render('tbody') %>");
$("tbody").prev().remove();
$("tbody").before("<%= j render(partial: 'thead', locals: {query: @query, order: @order}) %>");
var flag = $(".pagination").prev();
$(".pagination").remove();
flag.after("<%= j render('paginate') %>");
$(".pagination a").attr('data-remote', 'true')
-
最要注意的是怔揩,排序的ajax不要用post方法捉邢,用get方法就OK了!商膊!
這真的是太意外了伏伐,哈哈哈