更新:我已将此发布到github jquery-datatables-rails,因为它似乎是该gem的一个问题,或者更可能是我对它的使用。我在这里发布更新的副本以及更多描述以寻求帮助。请注意,当respond_to块执行两次时,数据表代码仅在块的第二次执行时执行。
我正在尝试将名为my_view的变量传递给Items Controller索引方法,以便我可以有选择地显示结果。当前代码工作,排序......最后,视图不会被维护,结果表中的任何操作(例如滚动)都会导致表格恢复显示所有项目而不是所需的选择。
基本问题是索引方法总是在单击按钮时执行两次。第一次正确设置my_view变量。第二次,总是零。 jquery-datatables-rails gem在两个pass上执行,可能涉及。几乎看起来我得到两个不同的交易。我甚至尝试过实例变量,在第二遍中它们也是零。我不明白这种情况发生的原因或原因。
To" fix"这个问题,我在第一次传递期间设置了session [:my_view],然后在第二次传递时不再设置它。在ItemsDatatable.new执行期间,我必须清除会话[:my_view],否则它将被保留用于下一个事务,给出不正确的结果。但是,这导致了我所说的问题,即对视图的任何更改(例如滚动)都会导致返回显示所有项目而不是所需的选择。
奇怪的是,我似乎没有任何其他控制器方法存在这种异常,或者至少没有注意到它。有人能告诉我为什么索引方法执行两次,以及我如何解决这个问题?谢谢!
EDIT UPDATE:我在admin命名空间中有另一个控制器,它使用带有HTML / JSON选项的respond_to。它也被执行两次,所以似乎可能(?)是相关的。丢失所有变量并第二次执行它仍然是一种奇怪的行为,但我不知道。是否相关,我该如何解决?感谢...
以下是我的按钮:
<%= link_to 'My Items', items_path(my_view: current_associate.id), class: 'btn btn-primary kc-wide' %>
<%= link_to 'All Items', items_path(my_view: "all"), class: 'btn btn-primary kc-wide' %>
使用索引方法的Items Controller:
class ItemsController < ApplicationController
def index
session[:my_view] ||= params[:my_view]
respond_to do |format|
format.html
format.json { render json: ItemsDatatable.new(view_context) }
end
end
end
相关路线,以防万一?
POST /items_index(.:format) items#index
items GET /items(.:format) items#index
POST /items(.:format) items#create
new_item GET /items/new(.:format) items#new
edit_item GET /items/:id/edit(.:format) items#edit
item GET /items/:id(.:format) items#show
PATCH /items/:id(.:format) items#update
PUT /items/:id(.:format) items#update
DELETE /items/:id(.:format) items#destroy
Rails数据表代码是:
class ItemsDatatable < ApplicationController
before_action :check_if_associate
delegate :params, :h, :link_to, :edit_item_path, :new_item_path, :location, to: :@view
def check_params(params)
# When using the .json suffix in URI, need to stub params so that I can see that JSON information
params[:draw] = 1 if params[:draw].blank?
params[:columns] = Array.new(1, {data: 0, name: '', searchable: true, orderable: true, search: {value: '', regex: false}}) if params[:columns].blank?
params[:order] = Array.new(1, {column: 0, dir: 'asc'}) if params[:order].blank?
params[:start] = 0 if params[:start].blank?
params[:length] = 10 if params[:length].blank?
params[:search] = {value: '', regex: false} if params[:search].blank?
end
def initialize(view)
@view = view
check_params(params)
@view
end
def as_json(options = {})
{
draw: params[:draw].to_i,
recordsTotal: Item.count,
recordsFiltered: items.total_entries,
data: data
}
end
private
def data
todays_date = Time.zone.now.to_date
items.map do |item|
status = item.status
# If current associate has it, show where it is.
if item.checkedout?(@view.current_associate)
status = "#{item.status}-#{item.lastloc}"
end
# If it's checked out but someone else has it, show who has it.
if item.not_available? and !item.checkedout?(@view.current_associate)
status = "#{item.status}-#{item.location}"
end
# Override the above if in return status, just showing that.
status = item.status == "Rtn" ? "Rtn" : status
odometer = item.odometer.to_s.gsub(/(\d)(?=(\d{3})+(?!\d))/, "\\1,")
msrp = item.msrp.to_s.gsub(/(\d)(?=(\d{3})+(?!\d))/, "\\1,")
age_date = item.age_date.nil? ? todays_date : item.age_date.to_date
[
link_to(item.stock_number, edit_item_path(item)),
ERB::Util.h(item.year),
ERB::Util.h(item.make),
ERB::Util.h(item.model),
ERB::Util.h(item.color),
ERB::Util.h(status),
ERB::Util.h(odometer),
ERB::Util.h(msrp),
ERB::Util.h((todays_date - age_date).to_i)
]
end
end
def items
@items ||= fetch_items
end
def fetch_items
items = Item.order("#{sort_column} #{sort_direction}")
items = items.includes(:item_location, item_location: [:locator])
items = items.includes(:key, key: [:key_location])
items = items.page(page).per_page(per_page)
unless @view.session[:my_view].blank? || @view.session[:my_view] == "all"
associate = Associate.find(@view.session[:my_view]).name
associate = associate.gsub(/'/, "''") # .gsub(/'/, "\\\\\'")
items = items.where("clshadow = \'#{associate}\'")
end
@view.session[:my_view] = nil
if params[:search][:value].present?
items = items.where("stock_number ilike :search or yrshadow ilike :search or mkshadow ilike :search or mdshadow ilike :search or coshadow ilike :search or status ilike :search", search: "%#{params[:search][:value]}%")
end
items
end
def page
params[:start].to_i/per_page + 1
end
def per_page
params[:length].to_i > 0 ? params[:length].to_i : 10
end
def sort_column
columns = %w[stock_number yrshadow mkshadow mdshadow coshadow status odometer msrp age_date]
columns[params[:order][0][:column].to_i]
end
def sort_direction
params[:order][0][:dir] == "desc" ? "desc" : "asc"
end
end
相关的JavaScript代码:
var itemstable = $('#itemstable').DataTable({
responsive: true,
autoWidth: false,
pagingType: 'full',
jQueryUI: true,
processing: true,
serverSide: true,
ajax: {
url: 'items_index.json',
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: function(d) {
return JSON.stringify(d);
}
},
columns: [null, null, null, null, null, null,
{className: 'dt-right'},
{className: 'dt-right'},
{className: 'dt-right'}
]
});
观点:
<div class="span9">
<p>
<table id="itemstable" class="display dt-responsive no-wrap table-striped" width="80%">
<thead>
<tr>
<th class="all">Stock No.</th>
<th class="all">Year</th>
<th class="all">Make</th>
<th class="min-tablet">Model</th>
<th class="min-tablet">Color</th>
<th class="all">Status</th>
<th class="desktop">Mileage</th>
<th class="desktop">MSRP</th>
<th class="desktop">Aged</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<%= link_to 'My Items', items_path(my_view: current_associate.id),
class: 'btn btn-primary kc-wide' %>
<%= link_to 'All Items', items_path(my_view: "all"),
class: 'btn btn-primary kc-wide' %>
<%= link_to 'Recent Items', x_logs_path,
class: 'btn btn-primary kc-wide' %>
<%= link_to 'Home', '/', class: 'btn btn-primary kc-wide' %>
</div>
答案 0 :(得分:0)
在第一次传递期间,gem似乎独立执行,而不将控制权转移到提供的代码,以便设置包含所有所需变量的参数列表。然后它似乎强制重新加载以根据需要使用参数列表启动该过程。我假设这是在第一次和第二次通过期间检查变量。在此过程中,它会忘记任何其他变量,但我不认为它应该这样做。
在任何情况下,我都必须使用会话变量来维护此重新加载期间的状态。我按如下方式更改了控制器索引,然后在我的数据表控制器中清除了会话[:my_view]的清除。
def index
unless params[:my_view].blank?
session[:requested_view] = params[:my_view]
end
session[:my_view] = session[:requested_view]
respond_to do |format|
format.html
format.json { render json: CarsDatatable.new(view_context) }
end
end
答案 1 :(得分:0)
试试这个: -
def index
session[:my_view] = params[:my_view] unless request.xhr?
respond_to do |format|
format.html
format.json { render json: ItemsDatatable.new(view_context) }
end
end