2015-06-26 42 views
1

如果用户单击复选框,则下面的代码将会触发,但复选标记有时会消失,因此应在选中该复选框时未勾选。消失的复选标记的奥秘

$(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 

以下是其中的gist。请不要犹豫,要求进一步的代码或澄清:]

我也遇到了这个问题,当我删除turbolinks认为可能是问题,但事实并非如此。

+0

单击复选框时是否触发页面加载? – fylooi

+0

此外,尝试将'page:change'更改为'page:load' – fylooi

+0

您可以尝试为复选框设置唯一的名称,可能是因为某些浏览器在单击名称相同的名称时会更改复选框的状态。 – jfornoff

回答

2

好吧,跟踪这个讨厌的人!

问题出现在您生成的HTML中。事实证明,有问题的人最终会执行AJAX调用...无效的URL(导致404的)!

在你放映视图,你有这样的代码:

<% 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 = $(this).parent().siblings(".habit-id").first().attr("id"); 
level = $(this).siblings(".level-id").first().attr("id"); 

尽管根据HTML从放映视图,有时会产生适当的类,有时也有类以的附录*-twohabit-id-twolevel-id-two)。

如果您尝试修复类名,那么所有表单都与JavaScript(.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" 
     }); 
    } 
    }); 
}); 

请注意,当生成删除-URL,我用的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%确定这是你想要的吗?

希望有帮助!如果您有任何问题 - 我非常乐意帮助/解释!

祝你好运!

+0

用你更简单的解决方案,我们得到:'ActionController :: UrlGenerationError in Habits#show Showing/Users/galli01anthony/Desktop/Pecoce/app/views/habits/show.html.erb其中第30行为: 没有路由匹配{:action =>“create”,:controller =>“days_missed”,:id =>“5”}缺少必需的键:[:habit_id,: level_id]' –

+0

这真是太神奇了。我一直在苦苦挣扎这么久!我会怎么做简单的版本,用'(.siblings(“。habit-id”)'和'.siblings(“。level-id”))' –

+0

想快速聊天吗? –