Vienas iš labiausiai netinkamai naudojamų, nesuprastų ir apleistų visų Bėgiai įmontuotos konstrukcijos yra vaizdo pagalbininkas . Įsikūręs jūsų app/helpers
katalogą ir pagal numatytuosius parametrus sugeneruojamus kiekviename naujame „Rails“ projekte, pagalbininkai dažnai gauna blogą reputaciją, nes yra vienkartinių metodų, naudojamų visame programos rodinio sluoksnyje, dempingo vieta. Deja, pats „Rails“ skatina šį struktūros trūkumą ir prastą organizavimą, pagal nutylėjimą įtraukdamas visus pagalbininkus į kiekvieną rodinį, sukurdamas užterštą pasaulinę vardų sritį.
Bet ką daryti, jei jūsų pagalbininkai galėtų būti prasmingesni, geriau organizuoti ir net pakartotinai naudojami visuose projektuose? Ką daryti, jei jos gali būti ne tik vienkartinės funkcijos, apibarstytos visame rodinyje, bet galingi metodai, kurie lengvai sukuria sudėtingą žymėjimą, o jūsų nuomonėse nėra sąlyginės logikos ir kodo?
Pažiūrėkime, kaip tai padaryti kuriant įvaizdžio karuselę, naudojant pažįstamą „Twitter Bootstrap“ sistemą ir seną gerą, objektyviai orientuotą programavimą.
Yra daug skirtingų dizaino modelių, kuriuos galima naudoti „Rails“ peržiūros sluoksnyje: vedėjai, dekoratoriai, daliniai, taip pat pagalbininkai, tik keli. Paprasta mano taisyklė: pagalbininkai puikiai dirba, kai norite sugeneruoti HTML žymėjimą, kuriam reikalinga tam tikra struktūra, specifinės CSS klasės, sąlyginė logika arba pakartotinis naudojimas skirtinguose puslapiuose.
Geriausią „Rails“ pagalbininkų galios pavyzdį demonstruoja FormBuilder
su visais susijusiais įvesties laukų generavimo metodais pasirinkite žymes, etiketes ir kitas HTML struktūras. Šie naudingi metodai sukuria žymėjimą jums tinkamai nustatant visus susijusius atributus. Toks patogumas, kodėl mes visi pirmiausia įsimylėjome Railsą.
Gerai parengtų pagalbininkų naudojimo pranašumai yra tokie patys kaip ir bet kokio gerai parašyto, švaraus kodo: įterpimas, kodo pasikartojimo sumažinimas (DRY) ir logikos nepastebėjimas.
„Twitter Bootstrap“ yra plačiai naudojama „front-end“ sistema integruotas palaikymas įprastų komponentų, tokių kaip modalai, skirtukai ir vaizdų karuselės. Šie „Bootstrap“ komponentai yra puikus pritaikymas pagalbiniams pagalbininkams, nes žymėjimas yra labai struktūrizuotas, norint, kad „JavaScript“ veiktų, reikia tinkamai nustatyti tam tikras klases, ID ir duomenų atributus, o norint nustatyti šiuos atributus, reikia šiek tiek sąlyginės logikos.
„Bootstrap 3“ karuselėje yra toks žymėjimas:
...
Kaip matote, yra trys pagrindinės struktūros: (1) indikatoriai (2) vaizdo skaidrės (3) skaidrės valdikliai.
Tikslas yra sugebėti sukurti vieną pagalbinį metodą, kuris imtų vaizdų rinkinį ir pateiktų visą šį karuselės komponentą, užtikrinant, kad duomenys, id
, href
atributai ir CSS klasės yra tinkamai nustatyti.
Pradėkime nuo pagrindinio pagalbininko metmenų:
# 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
Pagalbininko metodas carousel_for
grąžins visą nurodytų vaizdo URL karuselės žymėjimą. Užuot sukūrę atskirų metodų rinkinį kiekvienai karuselės daliai atkurti (tam prireiktų apeiti vaizdų rinkinį ir kitą reikšmingą informaciją kiekvienam metodui), mes sukursime naują „plain-old-Ruby“ klasę, vadinamą Carousel
reprezentuoti karuselės duomenis. Ši klasė parodys html
metodas, kuris grąžina visiškai pateiktą žymėjimą. Inicijuojame jį naudodami vaizdo URL rinkinį images
ir rodinio kontekstą view
Atkreipkite dėmesį, kad view
parametras yra ActionView
egzempliorius, į kurį įmaišomi visi „Rails“ pagalbininkai. Perduodame jį savo objekto egzemplioriui, kad galėtume pasiekti „Rails“ įmontuotus pagalbininkų metodus, tokius kaip link_to
, content_tag
, image_tag
ir safe_join
, kuriuos mes naudos kurdamas žymėjimą klasėje. Taip pat pridėsime delegate
makrokomanda , todėl tuos metodus galime vadinti tiesiogiai, nenurodydami view
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
Mes žinome, kad karuselę sudaro trys atskiri komponentai, todėl atsisakykime metodų, kurie galų gale suteiks mums kiekvieno žymėjimą, tada turėkime html
metodu sujunkite juos į konteinerį div
žymą, pritaikant būtinas „Bootstrap“ klases pačiai karuselei.
safe_join
yra patogus integruotas metodas, kuris sujungia stygų rinkinį ir ragina html_safe
dėl rezultato. Atminkite, kad mes turime prieigą prie tų metodų per view
parametras, kurį perdavėme kurdami egzempliorių.
def indicators items = images.count.times.map 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
Rodikliai yra paprastas užsakytas sąrašas ol
kuriame yra sąrašo elementas li
elementas kiekvienam kolekcijos vaizdui. Šiuo metu aktyviam vaizdo indikatoriui reikia active
CSS klasė, todėl įsitikinsime, kad ji nustatyta pirmajam mūsų sukurtam rodikliui. Tai puikus logikos pavyzdys, kuris paprastai turėtų būti pačiame vaizde.
Atkreipkite dėmesį, kad rodikliuose reikia nurodyti unikalų id
turinčio karuselės elemento (tuo atveju, jei puslapyje yra daugiau nei viena karuselė). Tai galime lengvai sugeneruoti id
inicializatoriuje ir naudokite jį visoje kitoje klasėje (ypač rodikliuose ir valdikliuose). Tai atlikus programiškai pagalbinio metodo viduje, užtikrinama, kad id
bus nuoseklūs visuose karuselės elementuose. Yra daug kartų, kai maža rašybos klaida arba pakeičiamas id
vienoje vietoje, bet ne kitos sukels karuselę; to čia nebus, nes visi elementai automatiškai nurodo tą patį id
def initialize(view, images) # ... @uid = SecureRandom.hex(6) end attr_accessor :uid
def slides items = images.map.with_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
Mes tiesiog kartojame kiekvieną vaizdą, kurį perdavome Carousel
egzempliorių ir sukurkite tinkamą žymėjimą: vaizdo žymę, suvyniotą į div
su item
CSS klasė, dar kartą būtinai pridėkite active
klasę į pirmą mūsų sukurtą.
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
Mes kuriame nuorodas, kurios kontroliuoja karuselės judėjimą pirmyn ir atgal tarp vaizdų. Atkreipkite dėmesį į uid
naudojimą vėl; nereikia jaudintis, kad nenaudosite tinkamo asmens tapatybės pažymėjimo visose skirtingose karuselės struktūros vietose, jis automatiškai yra nuoseklus ir unikalus.
Su tuo mūsų karuselės pagalbininkas yra baigtas. Čia jis yra visas:
# 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 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 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
Galiausiai, norėdami grįžti namo, pažvelkime į greitą pavyzdį, kaip šis pagalbininkas gali palengvinti mūsų gyvenimą. Tarkime, kad kuriame internetinių butų nuomos svetainę. Kiekvienas Apartment
objekte yra vaizdo URL sąrašas:
class Apartment def image_urls # ... end end
Naudodami savo karuselės pagalbininką, mes galime pateikti visą „Bootstrap“ karuselę vienu skambučiu į carousel_for
, visiškai pašalindami gana sudėtingą logiką iš rodinio:
# ...
Nežinote, kada naudoti „Rails“ peržiūros pagalbininkus? Štai demonstracija. Čivināšana Naudodamiesi šia paprasta, tačiau galinga technika, mes perėmėme žymimą žymėjimo ir logikos kiekį iš rodinio sluoksnio ir į pagalbinę funkciją, kurią galima naudoti kuriant karuselės komponentus bet kurioje vietoje naudojant tik carousel_for(some_images)
skambutis. Šis bendras pagalbininkas gali būti naudojamas visuose „Rails“ projektuose, kai naudojate „Twitter Bootstrap“. Svarbiausia, kad dabar savo įrankių rinkinyje turite naują įrankį, kurį taip pat galite naudoti konkretiems projektams skirtiems komponentams.
Taigi, kai kitą kartą pastebėsite, kad rašote ir perrašote tokio paties tipo žymėjimą ir įtrauksite sąlyginę logiką į savo nuomonę, pažiūrėkite, ar pagalbininko funkcija tiesiog laukia, kol bus parašyta, kad jūsų gyvenimas būtų lengvesnis.