如果用户单击一个复选框,则会触发以下代码,但是该复选框有时会消失,因此,应选中该复选框时,该复选框不会被选中。
$(document).on("page:change", function() { $(".habit-check").change(function() { habit = $(this).parent().siblings(".habit-id").first().attr("id"); level = $(this).siblings(".level-id").first().attr("id"); if($(this).is(":checked")) { $.ajax( { url: "/habits/" + habit + "/levels/" + level + "/days_missed", method: "POST" }); } else { $.ajax( { url: "/habits/" + habit + "/levels/" + level + "/days_missed/1", method: "DELETE" }); } }); }); # I ALSO TRIED USING LOCAL STORAGE, BUT IT HAD THE SAME PROBLEM. # VERSION 2 $(document).on("page:change", function() { { $(".habit-check").change(function() { habit = $(this).parent().siblings(".habit-id").first().attr("id"); level = $(this).siblings(".level-id").first().attr("id"); if ($(this).is(":checked")) { $.ajax({ url: "/habits/" + habit + "/levels/" + level + "/days_missed", method: "POST" }); localStorage.setItem("habit_"+habit+"_"+level, true); } else { $.ajax({ url: "/habits/" + habit + "/levels/" + level + "/days_missed/1", method: "DELETE" }); localStorage.setItem("habit_"+habit+"_"+level, false); } }); });
该 节目页面 调用AJAX
<div class="strikes"> <% if @habit.current_level_strike %> <div class="btn" id="red"> <label id="<%= @habit.id %>" class="habit-id">Strikes:</label> <% else %> <div class="btn" id="gold"> <label id="<%= @habit.id %>" class="habit-id-two">Strikes:</label> <% end %> <% @habit.levels.each_with_index do |level, index| %> <% if @habit.current_level >= (index + 1) %> <p> <% if @habit.current_level_strike %> <label id="<%= level.id %>" class="level-id">Level <%= index + 1 %>:</label> <% else %> <label id="<%= level.id %>" class="level-id-two">Level <%= index + 1 %>:</label> <% end %> <%= check_box_tag nil, true, level.missed_days > 0, {class: "habit-check"} %> <%= check_box_tag nil, true, level.missed_days > 1, {class: "habit-check"} %> <%= check_box_tag nil, true, level.missed_days > 2, {class: "habit-check"} %> </p> <% end %> <% end %> </div> </div>
这就是AJAX触发的 源代码days_missed_controller.rb 。
class DaysMissedController < ApplicationController before_action :logged_in_user, only: [:create, :destroy] def create habit = Habit.find(params[:habit_id]) habit.missed_days = habit.missed_days + 1 @habit.save! level = habit.levels.find(params[:level_id]) level.missed_days = level.missed_days + 1 if level.missed_days == 3 level.missed_days = 0 level.days_lost += habit.calculate_days_lost + 1 end level.save! head :ok # this returns an empty response with a 200 success status code end def destroy habit = Habit.find(params[:habit_id]) habit.missed_days = habit.missed_days - 1 habit.save! level = habit.levels.find(params[:level_id]) level.missed_days = level.missed_days - 1 level.save! head :ok # this returns an empty response with a 200 success status code end end
这是 要点 。请不要犹豫,要求进一步的代码或澄清:]
当我删除了turbolinks时,我也遇到了这个问题,但那不是问题。
好吧,追踪到这个讨厌的人!
问题出在您生成的HTML中。事实证明,有问题的最终以AJAX调用…无效的URL(导致404)!
404
在 show视图中 ,您具有以下代码:
<% if @habit.current_level_strike %> <div class="btn" id="red"> <label id="<%= @habit.id %>" class="habit-id">Strikes:</label> <% else %> <div class="btn" id="gold"> <label id="<%= @habit.id %>" class="habit-id-two">Strikes:</label> <% end %> <!-- [...] --> <% if @habit.current_level_strike %> <label id="<%= level.id %>" class="level-id">Level <%= index + 1 %>:</label> <% else %> <label id="<%= level.id %>" class="level-id-two">Level <%= index + 1 %>:</label> <% end %>
为什么会有问题?那么,在你的JavaScript,你依靠的确切类.habit-id和.level-id:
.habit-id
.level-id
habit = $(this).parent().siblings(".habit-id").first().attr("id"); level = $(this).siblings(".level-id").first().attr("id");
虽然根据 show view的 HTML 来看 ,有时会生成适当的类,有时会有些带有*-two(habit-id- two和level-id-two)附录的类。
*-two
habit-id- two
level-id-two
如果您尝试固定类名,那么它们的格式都与您的JavaScript(.siblings(".habit-id")和.siblings(".level- id"))期望的形式相同,则问题将消失。
.siblings(".habit-id")
.siblings(".level- id")
更好的解决方案 (是的,可以稍微简化一下;))
如果我们 预先生成 网址,并以如下方式在HTML中进行设置,该怎么办:
<div class="strikes"> <!-- [...] --> <% @habit.levels.each_with_index do |level, index| %> <% if @habit.current_level >= (index + 1) %> <p data-submit-url="<%= habit_level_days_missed_index_path({ habit_id: @habit.id, level_id: level.id }) %>" data-delete-url="<%= habit_level_days_missed_path({ habit_id: @habit.id, level_id: level.id, id: 1 }) %>"> <!-- [...] --> </p> <% end %> <% end %> </div> </div>
然后,您的JavaScript可以简化为:
$(document).on("page:change", 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")) { $.ajax( { url: submitUrl, method: "POST" }); } else { $.ajax( { url: deleteUrl, method: "DELETE" }); } }); });
请注意,在生成 delete-url时 ,我在中使用了的硬编码值id,该值是1(试图重现您的原始行为):
id
1
data-delete-url="<%= habit_level_days_missed_path({ habit_id: @habit.id, level_id: level.id, id: 1 }) %>"
对应于:
url: "/habits/" + habit + "/levels/" + level + "/days_missed/1"
在您的代码中。您是否 100% 确定这就是您想要的?
希望有帮助!如果您有任何疑问,我们非常乐于提供帮助/解释!
祝好运!