使用 JavaScript、Rails 以及 DataTables API 设置用于跟踪任务事件的报告界面。现在,我正在尝试弄清楚如何通过使用 JavaScript 连接界面的现有日期选择按钮(例如,今天、过去 7 天、过去 30 天等)来用新数据更新面向客户端的数据表在 Rails Controller 中的不同 time_range
参数值之间切换。
在 Controller 代码中,这些参数值之间的切换意味着会更新服务器端查询的 date_range
参数。此参数随后通过控制 db 命令的 WHERE 子句中指定的内容来过滤服务器端查询返回的数据。
我的问题是我在 JavaScript 中设置的获取请求显然无法对切换哪些参数值传递到控件产生任何影响流在 Controller 的 index
方法的顶部。
编辑
以下是单击“昨天”和“过去 7 天”日期选择按钮后开发工具中的网络 Pane 显示的内容。这些点击似乎正在运行成功的获取请求:
我应该在这里指出的另一件事是,从网络工具的预览中返回和查看的数据与我的“昨天”提取和“过去 7 天”提取的相同 。发出 fetch 请求的全部要点是,它通过与 Rails Controller 中编写的查询交互,检索根据界面中选择的日期范围定制的 json 数据结构。
在那里,使用 puts
在控制流 block 之后输出我的 @date_range
变量的值(用破折号 block 分隔此调试方面),Rails 控制台准确地报告了问题 - 我的客户端代码没有按预期更新@date_range
的值,但是,它确实显示顶部的 Parameters
哈希记录了传递给 time_range
的值更新的可见性:
Started GET "/task_reporting?time_range=yesterday" for ::1 at 2019-09-17 10:01:21 -0400
Processing by TaskReportingController#index as JSON
Parameters: {"time_range"=>"yesterday", "task_reporting"=>{}}
User Load (2.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
---------------------------------------------------------
The value of @date_range is >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
---------------------------------------------------------
(13.1ms) SELECT tasks.id, tasks.name, users.name, DATE_FORMAT(MAX(kits.updated_at), '%a. %b %d, %Y'),
COUNT(DISTINCT(DATE(kits.updated_at))), COUNT(DISTINCT(kits.id))
FROM kits
JOIN tasks ON tasks.id = kits.task_id JOIN users ON users.id = kits.user_id JOIN annotations ON annotations.kit_id = kits.id
WHERE kits.updated_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
GROUP BY tasks.id, users.name
Completed 200 OK in 39ms (Views: 1.3ms | ActiveRecord: 15.7ms)
Started GET "/task_reporting?time_range=last_seven_days" for ::1 at 2019-09-17 10:02:29 -0400
Processing by TaskReportingController#index as JSON
Parameters: {"time_range"=>"last_seven_days", "task_reporting"=>{}}
User Load (4.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
---------------------------------------------------------
The value of @date_range is >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
---------------------------------------------------------
(1.7ms) SELECT tasks.id, tasks.name, users.name, DATE_FORMAT(MAX(kits.updated_at), '%a. %b %d, %Y'),
COUNT(DISTINCT(DATE(kits.updated_at))), COUNT(DISTINCT(kits.id))
FROM kits
JOIN tasks ON tasks.id = kits.task_id JOIN users ON users.id = kits.user_id JOIN annotations ON annotations.kit_id = kits.id
WHERE kits.updated_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
GROUP BY tasks.id, users.name
Completed 200 OK in 18ms (Views: 1.1ms | ActiveRecord: 6.0ms)
结束编辑
<小时/>代码注释中描述了更多信息...
我的 JavaScript (task_reporting.js.coffee) 是从该工具的 View 代码末尾调用的:
Rails View (简化)
index.html.haml:
-content_for :action_specific_js do
!= "task_reporting.init()"
JavaScript(jQuery + CoffeeScript)
window.task_reporting = ( ->
// Important: initializes DataTable, loading default, thirty-day date-range data
init: () ->
this.init_datepicker_button()
this.init_daterange_buttons()
$("#tasks_report").DataTable
paging: false
scrollY: "400px"
scrollCollapse: true
sAjaxSource: "/task_reporting"
order: [[1, "asc"]]
// Important: Believe the problem is here.
// Method should send fetch request to server-side, altering query parameters in the controller
render_table: (passed_time_range) ->
query_params = "?time_range=#{passed_time_range}"
console.log(query_params)
fetch("/task_reporting#{query_params}",
method: 'GET'
headers:
"content-type": "application/json"
"Accept": "application/json"
credentials: "same-origin"
)
.then (response) -> response.json()
.then (data) ->
console.log(data)
$("#tasks_report").DataTable().clear().rows.add(data).draw
.catch((e) -> console.error("Error:", e))
// Not important: sets listener on date-range button (undeveloped)
init_datepicker_button: ->
dateRangeButton = $(".datepickerContainer > button#daterange")
dateRangeButton.on "click", this.init_dropdown
// Sets listeners on individual date range buttons, calling pass_time_range to set param value in fetch
init_daterange_buttons: ->
rangeItemButton = $(".range-item")
rangeItemButton.on "click", this.pass_time_range
init_dropdown: ->
console.log "dropdown here"
// Handles event on daterange buttons
// Passes param value to render_table according to button's class name
pass_time_range: (e) ->
e.preventDefault()
// console.log e
clickedTimeRange = e.target.className
if clickedTimeRange.includes "today"
task_reporting.render_table("today")
else if clickedTimeRange.includes "yesterday"
task_reporting.render_table("yesterday")
else if clickedTimeRange.includes "last_seven_days"
task_reporting.render_table("last_seven_days")
else if clickedTimeRange.includes "last_thirty_days"
task_reporting.render_table("last_thirty_days")
else if clickedTimeRange.includes "custom_range"
task_reporting.render_table("custom_range")
)()
Rails Controller
class TaskReportingController < ApplicationController
before_filter :authenticate
def index
# Checks param value and updates @date_range accordingly
if params[:time_range] == "range_today"
@date_range = '>= CURDATE()'
elsif params[:time_range] == "range_yesterday"
@date_range = '>= DATE_SUB(CURDATE(), INTERVAL 1 DAY)'
elsif params[:time_range] == "range_last_seven_days"
@date_range = '>= DATE_SUB(CURDATE(), INTERVAL 7 DAY)'
else params[:time_range] == "range_last_thirty_days"
@date_range = '>= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)'
end
# My fetch obviously fails to influence the :time_range param value
# as the default thirty day range is always output here
print <<-EOM
############
The value of @date_range is #{@date_range}
############
EOM
# heredoc query
query = <<-SQL
SELECT tasks.name, users.name, DATE_FORMAT(MAX(kits.updated_at), '%a. %b %d, %Y'),
COUNT(DISTINCT(DATE(kits.updated_at))), COUNT(DISTINCT(kits.id))
FROM kits
JOIN tasks ON tasks.id = kits.task_id JOIN users ON users.id = kits.user_id JOIN annotations ON annotations.kit_id = kits.id
WHERE kits.updated_at #{@date_range}
GROUP BY tasks.id, users.name
SQL
query_result = Kit.connection.execute(query).to_a
respond_to do |format|
format.html
format.json { render json: {"aaData": query_result} }
end
end
end
在我出错的地方寻找一些方向。欢迎就使用这样的 fetch 是否是使用 DataTables API 从客户端更新表数据的正确方法提出任何建议。
最佳答案
日志中您的参数值为“yesterday”或“last_seven_days”,但您的代码会检查“range_yesterday”或“range_last_seven_days”。这就是它失败并回落到默认范围的原因。
做类似的事情:
query_params = "?time_range=range_#{passed_time_range}"
或更改您的检查以与“昨天”而不是“range_yesterday”进行比较
关于javascript - JavaScript 的 Fetch 可以用来更新 Rails Controller 中的参数值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57962704/