当用户点击此内容时,我们如何自动重新加载页面?
<%= link_to '<span class="glyphicon glyphicon-remove"></span>'.html_safe, habit_level_days_missed_index_path({ habit_id: habit, level_id: habit.current_habit_level.id }), remote: true, method: 'post', data: { confirm: 'You missed a committed day?' }, class: 'habit-check', id: 'remove_check' %>
habit-check
触发了这个:
$(document).ready(function () {
$(".habit-check").change(function () {
var submitUrl = $(this).parents("p").data("submit-url");
var deleteUrl = $(this).parents("p").data("delete-url");
if ($(this).is(":checked")) { // We'd need to fix this line?
$.ajax({ url: submitUrl, method: "POST" }).done(location.reload)
} else {
$.ajax({ url: deleteUrl, method: "DELETE" }).done(location.reload)
}
})
})
但是这被设计为在单击复选框时起作用。如果单击link_to
按钮,我们如何才能使其工作?
我设想了类似if($(this).is(":checked && :clicked"))
的内容,但我对javascript几乎没有理解,但我希望你能得到这个想法:]
我尝试了此页https://api.jquery.com/category/selectors/中的所有选择器,但它们没有工作,所以我做错了或者解决方案不仅仅是修复一条线。
$(document).ready(function() {
$('.remove-check').on('ajax:success', function() { location.reload() })
$(".habit-check").change(function() {
var submitUrl = $(this).parents("p").data("submit-url");
var deleteUrl = $(this).parents("p").data("delete-url");
if($(this).is(":checked"))
{
$.ajax(
{
url: submitUrl,
method: "POST"
})
.done(function () {
location.reload();
});
}
else
{
$.ajax(
{
url: deleteUrl,
method: "DELETE"
})
.done(function () {
location.reload();
});
}
});
})
答案 0 :(得分:2)
似乎.habit-check
不再是复选框,因此处理更改事件的旧代码无法正常工作。
所以我假设您希望使用复选框的链接而不是来完成此工作。 我还假设您正在使用Rails jquery-ujs(不显眼的javascript与jQuery),这是现在的默认设置。
当您在链接或表单上指定remote: true
时,您不需要使用jQuery手动触发Ajax请求。 ujs框架为您做到了。因此,如果在data("submit-url")
(这是您的情况)中正确定义了路径,则不需要像link_to
那样在标记和javascript代码之间进行通信。这也是ujs框架的责任。
因此,当用户点击链接或提交具有remote: true
的表单时,ujs框架将与服务器通信,您只需在javascript中处理此处定义的Ajax事件之一:
https://github.com/rails/jquery-ujs/wiki/ajax
所以在你的情况下,这样做应该有效:
$(document).ready(function() {
$('.habit-check').on('ajax:success', function() { location.reload() })
})
或者这个(如果你的.habit-check
链接有可能由Javascript呈现,例如作为对Ajax调用的响应):
$(document).ready(function() {
$('body').on('ajax:success', '.habit-check', function() { location.reload() })
})
注意:如果您想使用ajax:success
事件,请确保您的控制器返回状态200.无论出于何种原因,如果控制器执行render text: 'hi'
,这将无法正常工作,因此呈现JSON回来或只是render nothing: true
。
更新 - 使用CHECKBOX
您似乎希望根据复选框状态调用不同的控制器操作。如果是这种情况,你可以像你一样在javascript中进行,或者按照我的建议在&#34;不同的控制器操作&#34;下面。如果您正好将复选框状态发送到一个控制器操作并让控制器处理&#34;如果选中,那么...&#34;,代码将更简单:
在再培训局:
<%= form_for @habit, remote: true, class: 'habit-form' do |f| %>
<%= f.check_box :check, class: 'habit-check' %>
<% end %>
在Javascript中:
$('.habit-check').on('change', function() { $('.habit-form').submit() })
$('.habit-form').on('ajax:success', function() { location.reload() })
在控制器中:
def update
habit = Habit.find(params[:id])
if params[:habit][:check] == '1'
# Do one thing
else
# Do another thing
end
render nothing: true
end
请注意,上面的代码做出以下假设:
您有一个名为Habit
的类,其中包含一个名为check
的属性。如果您不希望将此复选框属性作为db列,只需在attr_accessor :check
类定义中使用Habit
添加它,以便f.check_box :check
行生效。
ERB模板接收数据库中已存在的类@habit
的{{1}}对象。换句话说,Habit
会返回@habit.new_record?
。这将使表单与控制器中的false
操作进行通信。
不同的控制器操作
如果你想根据复选框状态调用不同的控制器操作,同时避免update
调用(我个人认为更干净),你可以渲染两种不同的形式并让javascript选择提交哪一种
在再培训局:
$.ajax
在javascript中:
<%= form_for @habit, url: destroy_habit_path, method: :delete, remote: true, class: 'destroy-form redirect-after-success' %>
<%= form_for Habit.new, url: habits_path, method: :post remote: true, class: 'create-form redirect-after-success' %>
请注意,您还可以将$('.habit-check').on('change', function() {
var isChecked = $(this).is(':checked');
var formClass = isChecked ? '.create-form' : '.destroy-form';
$(formClass).submit()
});
$('.redirect-after-success').on('ajax:success', function() { location.reload() });
课程添加到redirect-after-success
链接,这样上面的javascript代码就会支持,而不会更改我们初次讨论中的链接。