Rails Yardımcıları Nasıl Kullanılır: Bir Bootstrap Carousel Gösterisi

Yayınlanan: 2022-03-11

Tüm Rails yerleşik yapılarının en yanlış kullanılan, yanlış anlaşılan ve ihmal edilenlerinden biri view helper'dır . app/helpers dizininizde bulunan ve her yeni Rails projesinde varsayılan olarak oluşturulan yardımcılar, tüm uygulamanın görünüm katmanında kullanılan tek seferlik yöntemler için genellikle kötü bir üne sahiptir. Ne yazık ki, Rails'in kendisi, tüm yardımcıları varsayılan olarak her görünüme dahil ederek, kirli bir küresel ad alanı oluşturarak bu yapı eksikliğini ve zayıf organizasyonu teşvik eder.

Peki ya yardımcılarınız daha semantik, daha iyi organize edilmiş ve hatta projeler arasında yeniden kullanılabilir olsaydı? Ya görünüm boyunca serpiştirilmiş tek seferlik işlevlerden daha fazlası olabilirlerse, ancak görünümlerinizi koşullu mantık ve koddan arındırarak kolaylıkla karmaşık işaretlemeler oluşturan güçlü yöntemler olabilirse?

Tanıdık Twitter Bootstrap çerçevesi ve bazı eski moda nesne yönelimli programlama ile bir görüntü karuseli oluştururken bunu nasıl yapacağımızı görelim.

Rails yardımcıları ne zaman kullanılır?

Rails'in görünüm katmanında kullanılabilecek birçok farklı tasarım deseni vardır: sunucular, dekoratörler, kısmi öğeler ve yardımcılar, bunlardan sadece birkaçı. Basit kuralım, belirli bir yapı, belirli CSS sınıfları, koşullu mantık veya farklı sayfalarda yeniden kullanım gerektiren HTML işaretlemesi oluşturmak istediğinizde yardımcıların harika çalışmasıdır.

Rails yardımcılarının gücünün en iyi örneği, FormBuilder tarafından girdi alanları, seçili etiketler, etiketler ve diğer HTML yapıları oluşturmak için ilişkili tüm yöntemlerle gösterilmektedir. Bu yararlı yöntemler, uygun şekilde ayarlanmış tüm ilgili özniteliklerle sizin için işaretleme oluşturur. Bunun gibi kolaylıklar, hepimizin ilk etapta Rails'e aşık olmamızın nedenidir.

İyi hazırlanmış yardımcıları kullanmanın faydaları, iyi yazılmış, temiz kodlarla aynıdır: kapsülleme, kod tekrarının azaltılması (DRY) ve mantığı görünümden uzak tutma.

Twitter Bootstrap Carousel'in Anatomisi

Twitter Bootstrap, modlar, sekmeler ve görüntü karuselleri gibi yaygın bileşenler için yerleşik destekle birlikte gelen, yaygın olarak kullanılan bir ön uç çerçevesidir. Bu Bootstrap bileşenleri, özel yardımcılar için harika bir kullanım örneğidir, çünkü biçimlendirme yüksek düzeyde yapılandırılmıştır, JavaScript'in çalışması için belirli sınıfların, kimliklerin ve veri özniteliklerinin doğru ayarlanmasını gerektirir ve bu öznitelikleri ayarlamak biraz koşullu mantık gerektirir.

Bir Bootstrap 3 atlıkarınca aşağıdaki işaretlemeye sahiptir:

 <div class="carousel slide" data-ride="carousel"> <!-- Indicators --> <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li> <li data-target="#carousel-example-generic" data-slide-to="1"></li> <li data-target="#carousel-example-generic" data-slide-to="2"></li> </ol> <!-- Wrapper for slides --> <div class="carousel-inner"> <div class="item active"> <img src="..." alt="..."> </div> <div class="item"> <img src="..." alt="..."> </div> ... </div> <!-- Controls --> <a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> </a> <a class="right carousel-control" href="#carousel-example-generic" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> </a> </div>

Gördüğünüz gibi, üç ana yapı vardır: (1) göstergeler (2) görüntü slaytları (3) slayt kontrolleri.

Altına yakın üç küçük daire (göstergeler) ile ortalanmış geniş ekran oranlı bir dikdörtgeni (slayt) gösteren bir plan. Sırasıyla sol ve sağ okları olan iki ince dikdörtgenle çevrilidir (kontroller).
Bootstrap atlıkarıncasının parçaları.

Amaç, veri, id , href özniteliklerinin ve CSS sınıflarının tümünün doğru şekilde ayarlandığından emin olarak, bir görüntü koleksiyonu alan ve bu dönen bileşenin tamamını işleyen tek bir yardımcı yöntem oluşturabilmektir.

yardımcı

Yardımcının temel bir taslağıyla başlayalım:

 # app/helpers/carousel_helper.rb module CarouselHelper def carousel_for(images) Carousel.new(self, images).html end class Carousel def initialize(view, images) @view, @images = view, images end def html # TO FILL IN end private attr_accessor :view, :images end end

carousel_for yardımcı yöntemi, verilen resim URL'leri için tam atlıkarınca işaretlemesini döndürür. Atlıkarıncanın her bir bölümünü işlemek için bir dizi bireysel yöntem oluşturmak yerine (bu, her yönteme görüntü koleksiyonunu ve diğer durum bilgisini aktarmamızı gerektirir), Carousel adında yeni bir düz-eski Ruby sınıfı oluşturacağız. atlıkarınca verilerini temsil eder. Bu sınıf, tam olarak oluşturulmuş işaretlemeyi döndüren bir html yöntemini ortaya çıkaracaktır. Bunu, resim URL'leri images koleksiyonuyla ve görünüm bağlamı view .

view parametresinin, tüm Rails yardımcılarının karıştırıldığı bir ActionView örneği olduğunu unutmayın. Sınıf içinde işaretlemeyi oluşturmak için kullanacağımız link_to , content_tag , image_tag ve safe_join gibi Rails'in yerleşik yardımcı yöntemlerine erişmek için nesne örneğimize iletiyoruz. delegate makrosunu da ekleyeceğiz, böylece view öğesine başvurmadan bu yöntemleri doğrudan çağırabiliriz:

 def html content = view.safe_join([indicators, slides, controls]) view.content_tag(:div, content, class: 'carousel slide') end private attr_accessor :view, :images delegate :link_to, :content_tag, :image_tag, :safe_join, to: :view def indicators # TO FILL IN end def slides # TO FILL IN end def controls # TO FILL IN end

Bir dönencenin üç ayrı bileşenden oluştuğunu biliyoruz, bu yüzden sonunda bize her biri için işaretlemeyi verecek olan yöntemleri saplayalım, sonra html yönteminin bunları bir kapsayıcı div etiketine birleştirmesini sağlayalım ve atlıkarıncanın kendisi için gerekli Bootstrap sınıflarını uygulayalım.

safe_join , bir dizi diziyi bir araya getiren ve sonuçta html_safe çağıran kullanışlı bir yerleşik yöntemdir. Bu yöntemlere, örneği oluşturduğumuzda aktardığımız view parametresi aracılığıyla erişebildiğimizi unutmayın.

İlk önce göstergeleri oluşturacağız:

 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

Göstergeler, koleksiyondaki her görüntü için bir liste öğesi li öğesine sahip basit sıralı bir ol . Şu anda etkin olan görüntü göstergesinin active CSS sınıfına ihtiyacı var, bu nedenle oluşturduğumuz ilk gösterge için ayarlandığından emin olacağız. Bu, normalde görünümün kendisinde olması gereken harika bir mantık örneğidir.

Göstergelerin, içeren dönen öğenin benzersiz id başvurması gerektiğine dikkat edin (sayfada birden fazla dönen öğe olması durumunda). Bu id başlatıcıda kolayca oluşturabilir ve sınıfın geri kalanında (özellikle göstergeler ve kontroller içinde) kullanabiliriz. Bunu bir yardımcı yöntem içinde programlı olarak yapmak, id dönen öğeler arasında tutarlı olmasını sağlar. Küçük bir yazım hatasının veya bir yerde id değiştirilmesinin, diğerlerinin değil, bir atlıkarınca kırılmasına neden olacağı birçok zaman vardır; burada olmayacak çünkü tüm öğeler otomatik olarak aynı id .

 def initialize(view, images) # ... @uid = SecureRandom.hex(6) end attr_accessor :uid

Sıradaki resim slaytları:

 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

Carousel örneğine ilettiğimiz görüntülerin her birini yineliyoruz ve uygun işaretlemeyi oluşturuyoruz: CSS sınıfı item bir div içine sarılmış bir görüntü etiketi, yine active sınıfı ilk oluşturduğumuza eklediğinizden emin olun.

Son olarak, Önceki/Sonraki kontrollerine ihtiyacımız var:

 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, nil, class: "glyphicon glyphicon-chevron-#{direction}") control = link_to(icon, "##{uid}", options) end

Atlıkarıncanın görüntüler arasında ileri geri hareketini kontrol eden bağlantılar oluşturuyoruz. uid kullanımına tekrar dikkat edin; Karusel yapısı içindeki tüm farklı yerlerde doğru kimliği kullanmama konusunda endişelenmenize gerek yok, otomatik olarak tutarlı ve benzersiz.

Tamamlanmis urun:

Bununla, atlıkarınca yardımcımız tamamlandı. İşte tamamıyla:

 # app/helpers/carousel_helper.rb 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

Eylemdeki yardımcı:

Son olarak, konuyu eve götürmek için, bu yardımcının hayatımızı nasıl kolaylaştırabileceğine dair hızlı bir örneğe bakalım. Daire kiralama listeleri için bir web sitesi oluşturduğumuzu varsayalım. Her Apartment nesnesi, resim URL'lerinin bir listesine sahiptir:

 class Apartment def image_urls # ... end end

Carousel yardımcımızla, oldukça karmaşık mantığı görünümden tamamen kaldırarak, tüm Bootstrap carousel'ini carousel_for öğesine tek bir çağrıyla oluşturabiliriz:

 <% apartment = Apartment.new %> # ... <%= carousel_for(apartment.image_urls) %> 

Rails görüntüleme yardımcılarını ne zaman kullanacağınızdan emin değil misiniz? İşte bir gösteri.

Cıvıldamak

Çözüm

Bu basit, ancak güçlü tekniği kullanarak, önemli miktarda işaretleme ve mantık olacak olanı görünüm katmanından ve yalnızca bir carousel_for(some_images) çağrısıyla herhangi bir yerde carousel bileşenlerini oluşturmak için kullanılabilecek bir yardımcı işleve taşıdık. . Bu genel yardımcı, Twitter Bootstrap kullandığınızda tüm Rails projelerinizde kullanılabilir. En önemlisi, artık araç setinizde projeye özel bileşenler için de kullanabileceğiniz yeni bir araca sahipsiniz.

Bu nedenle, bir dahaki sefere aynı tür işaretlemeyi yazıp yeniden yazarken ve görüşlerinize koşullu mantık katarken bulursanız, hayatınızı kolaylaştırmak için bir yardımcı işlevin yazılmayı bekleyip beklemediğine bakın.