简体   繁体   English

如何使用 ajax 在 Rails 6 应用程序中显示 Bootstrap 4 模式?

[英]How can I use ajax to display Bootstrap 4 modal in Rails 6 app?

Currently I have a modal rendering for each piece on the page.目前,我对页面上的每一块都有一个模态渲染。 It works but I don't want to render a modal for each piece each time the page is loaded.它可以工作,但我不想在每次加载页面时为每个部分渲染一个模式。

Here is the code where my modal is rendered now:这是我的模态现在呈现的代码:

site/gallery.html.erb

<% @pieces.each_slice(3) do |pieces| %>
  <div class="row">
    <% pieces.each do |piece| %>
      <div class="col-lg-4">        
        <%= image_tag (piece.images.joins(:blob).order('active_storage_blobs.filename ASC').first if piece.images.attached?), data: { toggle: "modal", target: "#modal#{piece.id}" }, class:"img-thumbnail mx-auto d-block img-size" %>        
        <p><%= piece.name %></p>
        <p><%= piece.description %></p>
      <%= render 'site/modal', piece: piece %>
      </div>
    <% end %>
  </div>
<% end %>

Here is the modal partial:这是模态部分:

site/_modal.html.erb

<div class="modal fade" id="modal<%=piece.id%>" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="modalLabel"><%= piece.name %></h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        //code involving video and images for the piece
      </div>
      <div class="modal-footer">
        <% if piece.quantity == 1 %>
          <%= button_to 'Purchase', checkout_create_path, method: :post, params: {id: piece.id}, remote: true, class:"btn btn-dark" %>
        <% else %>
          <p>SOLD</p>
        <% end %>
      </div>
    </div>
  </div>
</div>

What I believe I need to do is add remote: true and pass the piece.id through my image_tag link somehow.我相信我需要做的是添加 remote: true 并以某种方式通过我的 image_tag 链接传递piece.id。 I think I would need a modal.js.erb with something along these lines in there我想我需要一个 modal.js.erb,里面有一些类似的东西

$('modal').html('<%= j render "site/modal", piece: @piece %>');
$('#modal<%=piece.id%>').modal('show');

And then render the modal at the top of the gallery.html.erb page.然后在gallery.html.erb页面顶部渲染modal。 I'm not quite sure how to go about this though我不太确定如何 go 关于这个虽然

EDIT I've made some progress with trying to use AJAX to display the modals.编辑我在尝试使用 AJAX 显示模式方面取得了一些进展。 I've moved my modal into the pieces directory and created a javascript file to go with it.我已经将我的模态移到了pieces目录中,并用它创建了一个javascript文件到go。

_piece_modal.html.erb

<div class="modal fade" id="piece-modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      //modal content here
    </div>
  </div>
</div>
piece_modal.js.erb

$('body').append('<%= j render "piece_modal", piece: @piece %>');
$('#piece-modal').modal('show');

In my pieces controller在我的作品中 controller

def piece_modal
  @piece = Piece.find_by(params[:piece])
end

In my routes在我的路线中

get 'piece_modal' => 'pieces#piece_modal'

And here is the loop I'm using images to link to my modals这是我使用图像链接到我的模态的循环

<% @pieces.each_slice(3) do |pieces| %>
  <div class="row">
    <% pieces.each do |piece| %>
      <div class="col-lg-4">
      <%= link_to piece_modal_path(piece), remote: true do %>        
        <%= image_tag (piece.images.joins(:blob).order('active_storage_blobs.filename ASC').first if piece.images.attached?), class:"img-thumbnail mx-auto d-block img-size" %>  
      <% end %>      
        <p><%= piece.name %></p>
        <p><%= piece.description %></p>
      </div>
    <% end %>
  </div>
<% end %>

The modal displays now but it only displays images from the first piece in the loop.模态现在显示,但它只显示循环中第一部分的图像。 How can I get it to display the correct content when I click on different images?当我点击不同的图像时,如何让它显示正确的内容?

Okay I found a way for the modal to load dynamically with some ajax.好的,我找到了一种使用 ajax 动态加载模态的方法。

I changed up my link_to like this我像这样改变了我的link_to

<%= link_to piece_modal_path(piece_id: piece.id), remote: true do %>

I made this change in the pieces controller我在 controller 中做了这个改变

def piece_modal
  @piece = Piece.find(params[:piece_id])
end

And I made this change to my piece_modal.js.erb我对我的piece_modal.js.erb做了这个改变

$('body').append('<%= j render "piece_modal", piece: @piece %>');
$('#piece-modal').modal('show'); 

$('#piece-modal').on('hidden.bs.modal', function () {
  $(this).remove();
});

So now instead of each piece on the site rendering it's own modal, only one gets rendered when I click on the image of the piece.所以现在不是网站上的每一块都呈现它自己的模式,当我单击该块的图像时,只有一个被呈现。 On hide though I have to remove it from the DOM or else the modal will stay rendered with the properties of the first piece I click on.在隐藏时,尽管我必须将其从 DOM 中删除,否则模态将保持呈现我单击的第一块的属性。

You have written your code like:您编写的代码如下:

  <%= image_tag (piece.images.joins(:blob).order('active_storage_blobs.filename ASC').first if piece.images.attached?), class:"img-thumbnail mx-auto d-block img-size" %> 

But notice that you use .first which will always return the first property.但请注意,您使用.first将始终返回第一个属性。

You could do something like this instead:你可以这样做:

<% @pieces.each_slice(3) do |pieces| %>
  <div class="row">
    <% pieces.each_with_index do |piece, index| %>
      <div class="col-lg-4">
      <%= link_to piece_modal_path(piece), remote: true do %>        
        <%= image_tag (piece.images.joins(:blob).order('active_storage_blobs.filename ASC')[index] if piece.images.attached?), class:"img-thumbnail mx-auto d-block img-size" %>  
      <% end %>      
        <p><%= piece.name %></p>
        <p><%= piece.description %></p>
      </div>
    <% end %>
  </div>
<% end %>

p/s: I'm writing this on the fly and didn't actually test it. p / s:我正在写这个,并没有实际测试它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM