【问题标题】:Rails 5, Bootstrap Carousel not rendering - setupRails 5,引导轮播不渲染 - 设置
【发布时间】:2016-11-05 09:23:05
【问题描述】:

我试图在我的 Rails 5 应用程序中使用图像轮播。我正在尝试遵循本文中的方法:https://www.toptal.com/ruby-on-rails/rails-helper-bootstrap-carousel

我有一个用于提案和图像的模型。这些关联是:

建议

has_many :images, as: :imageable
    accepts_nested_attributes_for :images,  reject_if: :all_blank, allow_destroy: true

图片

belongs_to :imageable, :polymorphic => true, optional: true

我的观点有:

    <!-- GALLERY -->

<div id="myCarousel" class="carousel slide" data-ride="carousel">

<!-- <div class="carousel-inner" role="listbox"> -->
 <% @images.each do |gallery| %>
    <% if gallery == @images.order(created_at: :asc).first%>
    <div class="item active">
     <%= carousel_for(gallery) %>
       <%= image_tag(gallery.picture.url, :class => "carousel_image", :style => "text-align: center" ) %> 
        <div class="carousel_caption">
            <p style="text-align: center"><%= gallery.comment.humanize %></p>  
            <p style="text-align: center"><%= gallery.credit %></p>
        </div>
      </div>
    <% else %>
     <div class="item">
    <%= carousel_for(gallery) %>
     <%= image_tag(gallery.picture, :class => "carousel_image") %>
      <div class="carousel_caption">
        <p style="text-align: center"><%= gallery.comment.humanize %></p>  
        <p style="text-align: center"><%= gallery.credit %></p>
      </div>
    </div> 
  <% end %>
<% end %>
<!-- </div> -->

  <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>
<!-- /GALLERY -->

助手有:

module CarouselHelper
  def carousel_for(images)
    Carousel.new(self, images).html
  end

  class Carousel
    def initialize(view, images)
      @view, @images = view, images
      @uid = SecureRandom.hex(6)
    end

    def html
      content = safe_join([indicators, slides, controls])
      content_tag(:div, content, id: uid, class: 'carousel slide')
    end

    private

    attr_accessor :view, :images, :uid
    delegate :link_to, :content_tag, :image_tag, :safe_join, to: :view

    def indicators
      items = images.count.times.map { |index| indicator_tag(index) }
      content_tag(:ol, safe_join(items), class: 'carousel-indicators')
    end

    def indicator_tag(index)
      options = {
        class: (index.zero? ? 'active' : ''),
        data: { 
          target: uid, 
          slide_to: index
        }
      }

      content_tag(:li, '', options)
    end

    def slides
      items = images.map.with_index { |image, index| slide_tag(image, index.zero?) }
      content_tag(:div, safe_join(items), class: 'carousel-inner')
    end

    def slide_tag(image, is_active)
      options = {
        class: (is_active ? 'item active' : 'item'),
      }

      content_tag(:div, image_tag(image), options)
    end

    def controls
      safe_join([control_tag('left'), control_tag('right')])
    end

    def control_tag(direction)
      options = {
        class: "#{direction} carousel-control",
        data: { slide: direction == 'left' ? 'prev' : 'next' }
      }

      icon = content_tag(:i, '', class: "glyphicon glyphicon-chevron-#{direction}")
      control = link_to(icon, "##{uid}", options)
    end
  end
end

我的 application.js 有:

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require jquery-fileupload/vendor/jquery.ui.widget
//= require jquery-fileupload/jquery.iframe-transport
//= require jquery-fileupload/jquery.fileupload
//= require bootstrap-sprockets
//= require moment
//= require bootstrap-datetimepicker
//= require pickers
//= require underscore
//= require gmaps/google
//= require markerclusterer
//= require cocoon
//= require_tree .

当我尝试这个时,我收到一条错误消息:

undefined method `count' for #<Image:0x007fb10c88bea8>

它突出显示了轮播的这一行(指标方法):

  items = images.count.times.map { |index| indicator_tag(index) }

阿伦的建议

<div id="myCarousel" class="carousel slide" data-ride="carousel">

<!-- <div class="carousel-inner" role="listbox"> -->
 <%# @images.each do |gallery| %>
    <%# if gallery == @images.order(created_at: :asc).first%>
    <div class="item active">
     <%= carousel_for(@images) %>
       <%= image_tag(@image.picture.url, :class => "carousel_image", :style => "text-align: center" ) %> 
        <div class="carousel_caption">
            <p style="text-align: center"><%= @image.comment.humanize %></p>  
            <p style="text-align: center"><%= @image.credit %></p>
        </div>
      </div>
    <%# else %>
     <div class="item">
    <%= carousel_for(@images) %>
     <%= image_tag(@image.picture, :class => "carousel_image") %>
      <div class="carousel_caption">
        <p style="text-align: center"><%= @image.comment.humanize %></p>  
        <p style="text-align: center"><%= @image.credit %></p>
      </div>
    </div> 
  <%# end %>
<%# end %>
<!-- </div> -->

  <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>
<!-- /GALLERY -->

错误提示:nil:NilClass 的未定义方法“图片”

第二次尝试 Arun 的建议

<div id="myCarousel" class="carousel slide" data-ride="carousel">

    <div class="item active">
     <%= carousel_for(@images) %>
       <%= image_tag(@image.picture.url, :class => "carousel_image", :style => "text-align: center" ) %> 
        <div class="carousel_caption">
            <p style="text-align: center"><%= @image.comment.humanize %></p>  
            <p style="text-align: center"><%= @image.credit %></p>
        </div>
      </div>
     <div class="item">
    <%= carousel_for(@images) %>
     <%= image_tag(@image.picture.url, :class => "carousel_image") %>
      <div class="carousel_caption">
        <p style="text-align: center"><%= @image.comment.humanize %></p>  
        <p style="text-align: center"><%= @image.credit %></p>
      </div>
    </div> 
<!-- </div> -->

  <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>
<!-- /GALLERY -->

错误提示:nil:NilClass 的未定义方法“图片”

Arun 的修改建议

采用 Arun 的修改建议,我尝试将整个画廊视图替换为:

<%= carousel_for(Image.all.map(&:picture_url)) %>     

当我尝试渲染页面时,会渲染第一张图片。我可以从 chrome 检查器中看到,第二张图像已被识别,尽管轮播不起作用。人字形不会移动图像。控制台中没有显示 js 问题。

【问题讨论】:

  • 不应该是@images.count.times.map { |index| indicator_tag(index) }吗?
  • @images 出现同样的错误
  • 为什么不发布有错误的代码?发布帮助文件的内容,以便我们了解发生了什么。
  • 对不起 - 我把它剪下来移动它并没有粘贴
  • 大家好,我是轮播助手文章的作者。几件事(1)对carousel_for的调用应该是视图中唯一的事情;助手会吐出 HTML 标记,因此您不应手动将其包含在内 (2) 您应该将一组图像 URL 传递给助手;这是一个字符串 URL 数组。如果轮播没有运行,请确保 Bootstrap 已加载并正常工作。

标签: ruby-on-rails ruby twitter-bootstrap carousel


【解决方案1】:

您需要执行 javascript 和 jquery 才能使此轮播正常工作。

在您的 html 文件末尾,添加以下代码(可以在 /body 之前):

<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script>
  $( document ).ready(function(){
  $('#mycarousel').carousel();
  });
</script>

您还可以使用此代码创建一个部分,并在应用程序布局结束时调用它。

【讨论】:

    【解决方案2】:

    问题在于您调用carousel_for 方法的方式。您应该传递一个图像数组,但是当您迭代 @images 时,您传递的是 Image 类型的单个实例。

    即。 Carousel 类中的images 不是ActiveRecord Relation。所以,你不能调用count 方法。错误消息清楚地表明您正在尝试在 image 实例上调用 count

    因此,您应该将@images 传递给carousel_for。你的视图应该只包含

    carousel_for(@images)
    

    编辑

    您实际上应该将图像 URL 数组传递给 carousel_for 方法。

    <%= carousel_for(Image.all.pluck(&:picture_url)) %>
    

    【讨论】:

    • 我尝试了这个建议(复制到帖子中)。它不起作用,而且,如何将第一张图像与其他图像分开,使其成为活动图像?
    • @Mel 更新了我的答案。您必须从 @images 集合中收集图像 URL,然后将其传递给帮助程序。
    • 我还是不明白。我将复制更新后的尝试(删除注释位)
    • @Mel 从视图中删除所有内容。你的视图应该只包含carousel_for(image_urls)
    • 这给出了这个错误:undefined local variable or method `image_urls' for #:0x007fb10bd21360> 你的意思是? image_url
    猜你喜欢
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多