كيفية استخدام مساعدي القضبان: عرض توضيحي دائري للتمهيد

نشرت: 2022-03-11

يعد مساعد العرض أحد أكثر الهياكل المدمجة في ريلز استخدامًا وإساءة فهمًا وإهمالًا. يقع في دليل app/helpers الخاص بك ويتم إنشاؤه افتراضيًا مع كل مشروع جديد من مشاريع Rails ، غالبًا ما يحصل المساعدون على سمعة سيئة لكونهم أرضية إغراق للأساليب التي تُستخدم لمرة واحدة عبر طبقة عرض التطبيق بالكامل. لسوء الحظ ، تشجع ريلز نفسها على هذا النقص في البنية والتنظيم الضعيف من خلال تضمين جميع المساعدين في كل طريقة عرض بشكل افتراضي ، مما يؤدي إلى إنشاء مساحة اسم عالمية ملوثة.

ولكن ماذا لو كان من الممكن أن يكون مساعدوك أكثر دلالة ، وأفضل تنظيماً ، بل ويمكن إعادة استخدامها عبر المشاريع؟ ماذا لو كان من الممكن أن تكون أكثر من مجرد وظائف لمرة واحدة يتم رشها في جميع أنحاء العرض ، ولكن الطرق القوية التي تولد ترميزًا معقدًا بسهولة تترك وجهات نظرك خالية من المنطق الشرطي والتعليمات البرمجية؟

دعونا نرى كيفية القيام بذلك عند إنشاء دائرة للصور ، باستخدام إطار عمل Twitter Bootstrap المألوف وبعض البرامج القديمة الجيدة الموجهة للكائنات.

متى تستخدم مساعدي ريلز

هناك العديد من أنماط التصميم المختلفة التي يمكن استخدامها في طبقة عرض ريلز: مقدمو العروض ، والديكورات ، والأجزاء الجزئية ، وكذلك المساعدون ، على سبيل المثال لا الحصر. قاعدتي الأساسية البسيطة هي أن المساعدين يعملون بشكل رائع عندما تريد إنشاء ترميز HTML يتطلب بنية معينة ، أو فئات CSS معينة ، أو منطقًا شرطيًا ، أو إعادة استخدام عبر صفحات مختلفة.

يوضح FormBuilder أفضل مثال على قوة مساعدي ريلز بكل الأساليب المرتبطة به لتوليد حقول الإدخال وتحديد العلامات والتسميات وهياكل HTML الأخرى. تعمل هذه الطرق المفيدة على إنشاء ترميز لك مع تعيين جميع السمات ذات الصلة بشكل صحيح. الراحة مثل هذا هو سبب وقوعنا جميعًا في حب ريلز في المقام الأول.

فوائد استخدام المساعدين المصنّعين جيدًا هي نفسها مثل أي رمز نظيف ومكتوب جيدًا: التغليف ، وتقليل تكرار الكود (DRY) ، وإبقاء المنطق بعيدًا عن الرؤية.

تشريح Twitter Bootstrap Carousel

Twitter Bootstrap عبارة عن إطار عمل للواجهة الأمامية مستخدم على نطاق واسع يأتي مع دعم مضمن للمكونات الشائعة مثل الوسائط وعلامات التبويب ودوارات الصور. تعد مكونات Bootstrap هذه حالة استخدام رائعة للمساعدين المخصصين لأن الترميز منظم للغاية ، ويتطلب تعيين فئات ومعرفات وسمات بيانات معينة بشكل صحيح لكي يعمل JavaScript ، ويتطلب تعيين تلك السمات القليل من المنطق الشرطي.

يحتوي دائري Bootstrap 3 على العلامات التالية:

 <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>

كما ترى ، هناك ثلاثة هياكل رئيسية: (1) المؤشرات (2) شرائح الصورة (3) عناصر التحكم في الشريحة.

مخطط يُظهر مستطيلاً مركزياً ذي نسبة شاشة عريضة (شريحة) مع ثلاث دوائر صغيرة بالقرب من قاعه (المؤشرات). يحيط به مستطيلان رفيعان بهما سهم لليسار ولليمين ، على التوالي (عناصر تحكم).
أجزاء دائري Bootstrap.

الهدف هو أن تكون قادرًا على بناء طريقة مساعدة واحدة تأخذ مجموعة من الصور وتعرض هذا المكون الدائري بالكامل ، مما يضمن تعيين سمات البيانات id و href وفئات CSS بشكل صحيح.

المساعد

لنبدأ بالخطوط العريضة الأساسية للمساعد:

 # 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 الترميز الدائري الكامل لعناوين URL للصور المحددة. بدلاً من إنشاء مجموعة من الأساليب الفردية لعرض كل جزء من الرف الدائري (الأمر الذي يتطلب منا المرور حول مجموعة الصور ومعلومات أخرى ذات حالة لكل طريقة) ، سننشئ فئة روبي جديدة بسيطة تسمى Carousel تمثل بيانات المكتبة. ستكشف هذه الفئة عن طريقة html تُرجع الترميز الذي تم تقديمه بالكامل. نقوم بتهيئته مع مجموعة من صور عناوين URL images ، وعرض سياق view .

لاحظ أن معلمة view هي مثيل لـ ActionView ، حيث يتم خلط جميع مساعدي ريلز. نقوم بتمريره إلى مثيل الكائن الخاص بنا من أجل الوصول إلى طرق المساعدة المضمنة في Rails مثل link_to و content_tag و image_tag و safe_join ، والتي سنستخدمها لإنشاء الترميز داخل الفصل. سنضيف أيضًا ماكرو delegate ، حتى نتمكن من استدعاء هذه الطرق مباشرةً ، دون الرجوع إلى 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

نحن نعلم أن الرف الدائري يتكون من ثلاثة مكونات منفصلة ، لذلك دعونا نستنتج طرقًا ستمنحنا في النهاية ترميزًا لكل منها ، ثم نجعل طريقة html تجمعهم في علامة div حاوية ، مع تطبيق فئات Bootstrap الضرورية للعرض الدائري نفسه.

safe_join هي طريقة مضمنة سهلة الاستخدام تجمع مجموعة من السلاسل معًا وتستدعي html_safe على النتيجة. تذكر ، لدينا إمكانية الوصول إلى هذه الطرق عبر معلمة 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

المؤشرات عبارة عن قائمة ol بسيطة تحتوي على عنصر قائمة li عنصر لكل صورة في المجموعة. يحتاج مؤشر الصورة النشط حاليًا إلى فئة CSS active ، لذلك سنتأكد من تعيينها لأول مؤشر نقوم بإنشائه. هذا مثال رائع على المنطق الذي يجب أن يكون عادة في العرض نفسه.

لاحظ أن المؤشرات تحتاج إلى الإشارة إلى id الفريد لعنصر الرف الدائري المحتوي (في حالة وجود أكثر من دائرة عرض واحدة في الصفحة). يمكننا بسهولة إنشاء هذا id في المُهيئ واستخدامه في بقية الفصل (تحديدًا ضمن المؤشرات وعناصر التحكم). يضمن القيام بذلك برمجيًا داخل أسلوب مساعد أن id سيكون متسقًا عبر عناصر المكتبة. هناك عدة مرات يؤدي فيها خطأ إملائي صغير أو تغيير id في مكان واحد ولكن ليس في الأماكن الأخرى إلى كسر دائرة دائرية ؛ لن يحدث ذلك هنا لأن جميع العناصر تشير تلقائيًا إلى نفس id .

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

التالي هو شرائح الصور:

 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 الترميز المناسب: علامة صورة ملفوفة في div مع فئة CSS item ، ومرة ​​أخرى نتأكد من إضافة الفئة active إلى أول صورة نقوم بإنشائها.

أخيرًا ، نحتاج إلى عناصر التحكم السابقة / التالية:

 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

ننشئ روابط تتحكم في حركة الرف الدائري ذهابًا وإيابًا بين الصور. لاحظ استخدام uid مرة أخرى ؛ لا داعي للقلق بشأن عدم استخدام المعرف الصحيح في جميع الأماكن المختلفة داخل هيكل الرف الدائري ، فهو متسق وفريد ​​من نوعه تلقائيًا.

المنتج المنتهي:

مع ذلك ، يكتمل مساعدنا الدائري. هنا هو في مجمله:

 # 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

المساعد في العمل:

أخيرًا ، لتوضيح هذه النقطة ، دعنا نلقي نظرة على مثال سريع عن كيف يمكن لهذا المساعد أن يجعل حياتنا أسهل. لنفترض أننا نبني موقعًا إلكترونيًا لقوائم إيجار الشقق. يحتوي كل كائن Apartment على قائمة عناوين URL للصورة:

 class Apartment def image_urls # ... end end

من خلال المساعد الدائري الخاص بنا ، يمكننا عرض مكتبة Bootstrap بالكامل باستدعاء واحد إلى carousel_for ، وإزالة المنطق المعقد تمامًا من العرض:

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

ألست متأكدًا من موعد استخدام مساعدي عرض ريلز؟ هذا عرض توضيحي.

سقسقة

خاتمة

باستخدام هذه التقنية البسيطة والفعالة في نفس الوقت ، نقلنا ما يمكن أن يكون قدرًا كبيرًا من الترميز والمنطق من طبقة العرض إلى وظيفة مساعدة يمكن استخدامها لعرض مكونات دائرية في أي مكان باستخدام استدعاء carousel_for(some_images) . يمكن استخدام هذا المساعد العام في جميع مشاريع ريلز الخاصة بك عندما تستخدم Twitter Bootstrap. الأهم من ذلك ، لديك الآن أداة جديدة في مجموعة الأدوات الخاصة بك والتي يمكنك استخدامها للمكونات الخاصة بالمشروع أيضًا.

لذلك ، في المرة القادمة التي تجد فيها نفسك تكتب وتعيد كتابة نفس النوع من الترميز وتضمين المنطق الشرطي في وجهات نظرك ، تحقق مما إذا كانت الوظيفة المساعدة تنتظر كتابتها فقط لجعل حياتك أسهل.