如何动态加载Rails中的数据 4

How to dynamically load data in Rails 4

所以我的这个页面具有创建新课程并在同一页面上列出所有课程的功能。

我想要的是,当我单击课程 ID 时,动态加载与该 ID 相关联的所有课程 div。

这是index.html.erb门课程

<% provide(:title, 'All courses') %>
<h1>All Courses </h1>
<p><%= link_to "Back", admin_path, class: "btn-submit" %></p>

<div class="text-center">
  <%= form_for [:admin, @course] do |f|%>
  <%= render 'shared/error_messages', object: f.object %>
  <p>
    Create a new course
  </p>

    <%= f.label :title%>
    <%= f.text_field :title%>

    <%= f.label :description%>
    <%= f.text_area(:description, size: "24x2") %>

    <%= f.label :duration%>
    <%= f.number_field(:duration, step: 0.5) %>

    <%= f.label :category%>
    <%= f.text_field(:category) %>

    <%= f.label :tag%>
    <%= f.text_field(:tag) %>


    <%= f.submit "Create Course", class: "btn-submit" %>
  <% end %>
</div>

<table class="display responsive no-wrap text-center" id="datatableadmin">
  <thead>
    <tr>
      <th>id</th>
      <th>Title</th>
      <th>Description</th>
      <th>Duration</th>
      <th>Category</th>
      <th>Tag</th>
      <th>Deletion</th>
    </tr>
  </thead>
  <tbody>
    <% @courses.each do |c| %>
      <tr>
        <td><%= c.id %></td>
        <td><%= best_in_place c, :title, url: "courses/#{c.id}", cancel_button: 'X' %></td>
        <td><%= best_in_place c, :description, url: "courses/#{c.id}" %></td>
        <td><%= best_in_place c, :duration, url: "courses/#{c.id}" %></td>
        <td><%= best_in_place c, :category, url: "courses/#{c.id}" %></td>
        <td><%= best_in_place c, :tag, url: "courses/#{c.id}" %></td>
        <td><%= link_to "Remove", admin_course_path(c), method: :delete, data: { confirm: "Are you sure?" }%></td>
      </tr>
    <% end %>
  </tbody>
</table>
<div class="text-center">
  <small style="color:red;">Edit by clicking the fields and pressing enter. Cancel by clicking the X button</small>
</div>

所以基本上,如果您往下看 c.id,我希望该功能能够在单击该 ID 时调用与该 ID 关联的所有课程。

我认为最简单的 AJAX 解决方案是为每个 ID 添加一个 link_to 并添加相关的服务器端代码,如下所示。

<tbody>
    <% @courses.each do |c| %>
      <tr>
        <td><%= link_to(c.id, course_lessons_path(c), remote: :true) %></td>

routes.rb

resources :courses do
  resources :lessons
end

lessons_controller.rb

  def index
    find_lessons
    respond_to do |format|
      # Your other formats
      format.js
    end
  end

  def find_lessons
    if params[:course_id]
      @lessons = Course.find(params[:course_id]).lessons
    else
      # Error or @lessons = Lesson.all
    end
  end

lessons/index.js

var where = $("ul#where-to-load-lesson-id")
where.empty() # Reset list
<% @lessons.each do  |lesson| %>
  # Simple working code
  $('.lessons').append('<li><%= lesson.title %></li>');

  # Advanced code for nested for loops that could use debugging
  # To use if you have nested properties (`lesson has_many exercises`)
  var li = $("<li>", { 
    'class': 'lesson', 
    'html': '<%= lesson.content %>' }
  ).appendTo(where)
  var ex_list = $("<ul>", { 'class': 'exercise-list' }).appendTo(li)
  <% lesson.exercises.each_with_index do |ex, i| %>
      ex_list.append('<li><%= link_to("exercise #{i}", exercice_path(ex)) %></li>');
  <% end %>
<% end %>

因为 Cyril DD 有 ajax 解。我将在这里编写预取解决方案。建议只在有少量课时使用,通常不超过 2 位数。我想课程不会那么长。

<% @courses.each do |c| %>
      <tr>
        <td class="course_id" data-id="<%= c.id %>">
          <%= c.id %>         
        </td>
        <td><%= best_in_place c, :title, url: "courses/#{c.id}", cancel_button: 'X' %></td>
        <td><%= best_in_place c, :description, url: "courses/#{c.id}" %></td>
        <td><%= best_in_place c, :duration, url: "courses/#{c.id}" %></td>
        <td><%= best_in_place c, :category, url: "courses/#{c.id}" %></td>
        <td><%= best_in_place c, :tag, url: "courses/#{c.id}" %></td>
        <td><%= link_to "Remove", admin_course_path(c), method: :delete, data: { confirm: "Are you sure?" }%></td>
      </tr>
<% end %>
///other markups.....
<%= @courses.each do|c| %>
<div id='<%= "lessons_by_course_#{c.id}"%>' class='someClassWithDisplayNone'>
  <%= render partial: "lessons", {locals: {lesson: c.lessons}} %>
</div>
<% end %>

然后在javascript

$(function(){
  $(".course_id").on("click", function(){
    var id = $(this).data("id");
    $("#lessons_by_course_" + id).removeClass("someClassWithDisplayNone");
  });
})();

当然,这个解决方案假设了一些事情,例如存在部分 lessons 用于呈现课程(您也可以编写没有部分的直接标记)以及课程和课程之间存在一对多关系教训。否则,我相信所有代码都是自我解释的。

跟进 Cyril DD 的响应,这是正确的,因为 Cyrils 代码存在一些问题。

在我的 courses/index.html.erb

<td><%= link_to(c.id, admin_course_lessons_path(c), remote: :true) %></td>

at the bottom i have
<ul class="lessons"></ul>

在我的 routes.rb

resources :lessons do
  resources :courses
end

在我的 lessons_controller.rb

def index
    find_lessons
    respond_to do |format|
      format.html
      format.js
    end
  end

  def find_lessons
       if params[:course_id]
         @lessons = Course.find(params[:course_id]).lessons
       else
         @lessons = Lesson.all
         @lesson = Lesson.new
       end
   end

在我的index.js.erb文件里面admin/lessons/文件夹

$('.lessons').empty();
<% @lessons.each do |l| %>
$('.lessons').append('<li><%= l.title %></li>');
<% end %>