প্রতিক্রিয়া দ্বারা অনুপ্রাণিত, ViewComponents হল রুবি অবজেক্ট যা ভিউ রেন্ডার করার জন্য মার্কআপ তৈরি করতে ব্যবহৃত হয়। ভিউ কম্পোনেন্ট হল রেলে পুনরায় ব্যবহারযোগ্য, পরীক্ষাযোগ্য এবং এনক্যাপসুলেটেড ভিউ উপাদান তৈরির জন্য একটি কাঠামো। সাধারণত, পুনঃব্যবহারযোগ্য দৃশ্যগুলি আংশিক ব্যবহার করে রেলগুলিতে তৈরি করা হয় এবং তারপরে প্রয়োজন অনুসারে বিভিন্ন ভিউতে রেন্ডার করা হয়, তবে ভিউ কম্পোনেন্ট রত্ন প্রবর্তনের সাথে, আংশিকগুলি ভিউ উপাদানগুলির জন্য অদলবদল করা যেতে পারে, কারণ তারা আরও সুবিধা দেয়। আসুন এই সুবিধাগুলি কী তা জেনে নিই৷
৷আমি কখন এবং কেন ভিউ কম্পোনেন্ট ব্যবহার করব?
পূর্বে বলা হয়েছে, ভিউ উপাদানগুলি পুনরায় ব্যবহারযোগ্য এবং পরীক্ষাযোগ্য। তাই, যখনই কোনো দৃশ্য পুনরায় ব্যবহার করা হবে বা সরাসরি পরীক্ষা করার সুবিধা হবে তখনই এগুলি প্রয়োগ করা যেতে পারে। দেখার উপাদানগুলির কিছু সুবিধা, যেমন এর ডকুমেন্টেশনে বলা হয়েছে, নিম্নলিখিতগুলি অন্তর্ভুক্ত করে:
- এগুলি আংশিকগুলির চেয়ে ~10x দ্রুত৷ ৷
- এগুলি রুবি বস্তু; তাই, তাদের ইনিশিয়ালাইজ পদ্ধতি স্পষ্টভাবে সংজ্ঞায়িত করে যে একটি ভিউ রেন্ডার করার জন্য কী প্রয়োজন। এর মানে হল যে সেগুলি বোঝা সহজ এবং অন্য কয়েকটি দৃশ্যে পুনরায় ব্যবহার করা। উপরন্তু, রুবি কোডের মানের মান প্রয়োগ করা যেতে পারে, যার ফলে বাগগুলির ঝুঁকি হ্রাস পায়।
- এগুলিকে রেলের ঐতিহ্যগত দৃষ্টিভঙ্গির বিপরীতে একক পরীক্ষা করা যেতে পারে, যার জন্য ইন্টিগ্রেশন পরীক্ষার প্রয়োজন হয় যা ভিউ ছাড়াও রাউটিং এবং কন্ট্রোলার স্তরগুলিও অনুশীলন করে।
ভিউ কম্পোনেন্ট ইমপ্লিমেন্টেশন
ViewComponents হল ViewComponent::Base
এর সাবক্লাস এবং app/components
-এ বাস করুন . তাদের নাম - Component
দিয়ে শেষ হয় , এবং তারা যা প্রদান করে তার জন্য তাদের নামকরণ করা উচিত এবং তারা যা গ্রহণ করে তা নয়। আমরা ম্যানুয়ালি বা কম্পোনেন্ট জেনারেটরের মাধ্যমে একটি ভিউ কম্পোনেন্ট তৈরি করতে পারি, কিন্তু আমাদের জেমফাইলে রত্ন যোগ না করে এবং একটি bundle install
চালানো ছাড়া নয়। প্রথম।
gem "view_component", require: "view_component/engine"
জেনারেটর ব্যবহার করতে, নিম্নলিখিত কমান্ডটি চালান:
rails generate component <Component name> <arguments needed for initialization>
উদাহরণ স্বরূপ, যদি আমরা একটি লার্নিং প্ল্যাটফর্মে উপলব্ধ ক্লাসের কোর্সগুলির একটি তালিকা প্রদর্শনের জন্য দায়ী একটি উপাদান তৈরি করতে চাই, আমরা এই কমান্ডটি ব্যবহার করতে পারি:
rails g component Course course
আমরা course
পাশ করছি কমান্ডের যুক্তি কারণ আমরা এই রুবি অবজেক্টটি যে কোর্সটি প্রদর্শন করার আশা করি তার সাথে শুরু করব এবং আমরা এটির নাম দিয়েছি course
কারণ এটি একটি কোর্স রেন্ডার করে। কি কাকতালীয়!
আমরা উপরে দেখতে পাচ্ছি, কম্পোনেন্ট এবং এর সংশ্লিষ্ট ভিউ app/components
-এ তৈরি করা হয়েছে ফোল্ডার, একটি টেস্ট ফাইল সহ।
ViewComponent-এ erb
-এর জন্য টেমপ্লেট জেনারেটর রয়েছে , haml
, এবং slim
টেমপ্লেট ইঞ্জিন কিন্তু config.generators.template_engine
-এ নির্দিষ্ট করা যাই হোক না কেন টেমপ্লেট ইঞ্জিন ডিফল্ট হবে তবুও, আপনি নিম্নলিখিত ব্যবহার করে আপনার পছন্দের টেমপ্লেট ইঞ্জিন নির্দেশ করতে পারেন:
rails generate component Course course --template-engine <your template engine>
আসুন আমাদের কোর্স মডেল এবং প্রদর্শনের জন্য কিছু কোর্স তৈরি করতে এগিয়ে যাই।
rails g model Course title:string price:decimal location:string
rails db:migrate
আমাদের কনসোলে, আমরা দ্রুত দুটি নতুন কোর্স তৈরি করতে পারি:
Course.create(title: 'The Art of Learning', price: 125.00, location: 'Denmark')
Course.create(title: 'Organizing your Time', price: 55.00, location: 'London')
course_component.rb
ফাইলটি ইনিশিয়ালাইজ পদ্ধতিতে তৈরি করা হয়, যেমনটি নীচে দেখানো হয়েছে।
আমাদের একটি কোর্স কন্ট্রোলার তৈরি করতে হবে যা আমাদেরকে কোর্সের তালিকায় নিয়ে যায়।
rails g controller Courses index
আমাদের routes.rb
-এ ফাইলে, আমরা নিম্নলিখিত যোগ করে আমাদের রুট রুট নির্দেশ করি:
root 'courses#index'
এখন আমরা সব প্রস্তুত, পরবর্তী ধাপ হল ভিউ তৈরি। এটি ইতিমধ্যেই তৈরি করা course_component.html.erb
এ করা হয়েছে .
<div>
<h2><%= @course.title %></h2>
<h4><%= number_to_currency(@course.price, :unit => "€") %></h4>
<h4><%= @course.location %></h4>
</div>
আমাদের দৃষ্টিতে, আমরা @course
ব্যবহার করে কোর্সের শিরোনাম, মূল্য এবং অবস্থান প্রদর্শন করি ভেরিয়েবল, যা ইতিমধ্যেই আমাদের কোর্স কম্পোনেন্টের প্রাথমিক পদ্ধতিতে সংজ্ঞায়িত করা হয়েছে। আপনি যখন একটি কন্ট্রোলার পদ্ধতিতে একটি ভেরিয়েবল তৈরি করেন তখন এটি একটি ভিউতে পাওয়া যায়।
কন্ট্রোলাররা কীভাবে কাজ করে তা জেনে, আমরা সংশ্লিষ্ট index.html.erb
-এ রুট করা হবে আমাদের সূচক পদ্ধতির। তাই, এখানেই আমরা আমাদের উপাদান রেন্ডার করি।
#app/views/courses/index.html.erb
<%= render(CourseComponent.new(course: Course.find(1))) %>
উপরে যেমন দেখা গেছে, আমরা আমাদের কোর্স কম্পোনেন্টের একটি নতুন দৃষ্টান্ত রেন্ডার করি যে কোর্সের সাথে আমরা এটিকে এর দৃশ্যে রেন্ডার করতে চাই। এই কোর্সটি @course
হয়ে যায় পরিবর্তনশীল course_component.html.erb
এ উপলব্ধ করা হয়েছে ফাইল।
আমাদের নিয়ামক থেকে সরাসরি এই উপাদানটি রেন্ডার করাও সম্ভব, যার ফলে সূচী ফাইলের দৃশ্যকে বাইপাস করে:
class CoursesController < ApplicationController
def index
render(CourseComponent.new(course: Course.find(1)))
end
end
আপনি যে পদ্ধতিটি বেছে নিন তা নির্বিশেষে, এটি সার্ভারে প্রদর্শিত হবে:
অতিরিক্ত বিষয়বস্তু নিম্নোক্ত উপায়গুলির একটিতেও কম্পোনেন্টে পাঠানো যেতে পারে:
<%= render(CourseComponent.new(course: Course.find(1))) do %>
container
<% end %>
<%= render(CourseComponent.new(course: Course.find(1)).with_content("container")) %>
আমাদের ভিউ কম্পোনেন্ট ফাইলে, আমরা যেখানে চাই কন্টেন্ট অন্তর্ভুক্ত করতে পারি। এই ক্ষেত্রে, আমরা আমাদের ডিভ সম্পাদনা করে এটিকে একটি শ্রেণি হিসাবে অন্তর্ভুক্ত করব এইরকম দেখতে:
<div class=<%= content %>>
অতিরিক্ত বিষয়বস্তু রেন্ডার করার উপরের সমস্ত পদ্ধতি নীচের চিত্রটি দেয়:
একটি সংগ্রহ রেন্ডার করা
আমরা যদি আমাদের কোর্সের সম্পূর্ণ তালিকা রেন্ডার করতে চাই? ViewComponent with_collection
ব্যবহার করে এটি করার একটি খুব সোজা পথ প্রদান করে ট্যাগ .new
ব্যবহার করে কম্পোনেন্ট আরম্ভ করার পরিবর্তে , এটি .with_collection
ব্যবহার করে আরম্ভ করা হয় , এবং সংগ্রহটি একটি পরিবর্তনশীল হিসাবে এটিতে প্রেরণ করা হয়েছে, যেমনটি নীচে দেখানো হয়েছে।
CourseComponent.with_collection(Course.all)
এটি নিম্নলিখিত ফল দেয়:
এছাড়াও একটি with_collection_parameter
আছে ট্যাগ পাওয়া যায় যদি আমরা সংগ্রহটিকে অন্য নামে সম্বোধন করতে চাই।
class CourseComponent < ViewComponent::Base
with_collection_parameter :item
def initialize(item:)
@item = item
end
end
উপরের ক্ষেত্রে, কোর্স প্যারামিটারটিকে item
হিসাবে সম্বোধন করা হয়েছে . তাই, সংশ্লিষ্ট দৃশ্যে, @course
@item
দিয়ে প্রতিস্থাপিত হবে একই ফলাফল দিতে।
সংগ্রহে অতিরিক্ত প্যারামিটার যোগ করা যেতে পারে। এই পরামিতি সংগ্রহে আইটেম প্রতি প্রদর্শিত হবে. চলুন একটি Buy Me
যোগ করি এই পদ্ধতির মাধ্যমে প্রতিটি আইটেমে পাঠ্য।
#app/views/courses/index.html.erb
<%= render(CourseComponent.with_collection(Course.all, notice: "Buy Me")) %>
# app/components/course_component.rb
class CourseComponent < ViewComponent::Base
with_collection_parameter :item
def initialize(item:, notice:)
@item = item
@notice = notice
end
end
আমরা app/components/course_component.html.erb
এ একটি নতুন অনুচ্ছেদ যোগ করি সদ্য যোগ করা নোটিশ ভেরিয়েবলের পাঠ্য নির্দেশ করার জন্য ফাইল।
<p><a href='#'> <%= @notice %> </a></p>
এটি নিম্নলিখিত ফল দেয়:
অবশেষে, সংগ্রহের অধীনে, আমাদের একটি কাউন্টার ভেরিয়েবল আছে যা একটি ভিউতে আইটেমগুলিকে সংখ্যা করতে সক্ষম করা যেতে পারে। এটি _counter
যোগ করে সক্রিয় করা হয়েছে সংগ্রহের প্যারামিটারে এবং ইনিশিয়ালাইজ পদ্ধতির মাধ্যমে ভিউয়ের জন্য উপলব্ধ করা।
#app/components/course_component.rb
def initialize(item:, notice:, item_counter:)
@item = item
@notice = notice
@counter = item_counter
end
আমাদের মতামতে, আইটেমের শিরোনামের পাশে, আমরা আমাদের কাউন্টার যোগ করি:
<h2><%= @counter %>. <%= @item.title %></h2>
পাল্টা ঘটনাটি আরও ভালভাবে বুঝতে কনসোল থেকে একটি তৃতীয় কোর্স তৈরি করি৷
Course.create(title: 'Understanding Databases', price: '100', location: 'Amsterdam')
এটি নিম্নলিখিত ফল দেয়
শর্তসাপেক্ষ রেন্ডারিং
ViewComponent এর একটি render?
আছে হুক, যা ব্যবহার করার সময়, একটি ভিউ রেন্ডার করা উচিত কিনা তা নির্ধারণ করে। এটি বাস্তবায়নের জন্য, আমরা 100 ইউরোর সমান বা তার বেশি মূল্য সহ কোর্সের জন্য 10% ছাড় দিতে যাচ্ছি। আসুন এই উদ্দেশ্যে একটি উপাদান তৈরি করি।
rails generate component Discount item
এই উপাদানটি ইতিমধ্যেই স্বয়ংক্রিয়ভাবে শুরু করা হয়েছে আইটেমের সাথে এটির জন্য একটি ছাড় প্রদর্শন করা উচিত, যেমনটি নীচে দেখানো হয়েছে৷
তাই, discount_component.html.erb
-এ ফাইলে, আমরা যে পাঠ্যটি প্রদর্শন করতে চাই তা যুক্ত করি।
<p class="green"> A 10% discount is available on this course </p>
green
ক্লাস যোগ করতে দ্বিধা করবেন না আপনার সিএসএস ফাইলে এবং আপনার পছন্দের সবুজ রঙের যে কোনো শেড বরাদ্দ করুন। উপরন্তু, আমাদের discount_component.rb
-এ ফাইল, আমরা render?
যোগ করি এই উপাদানটি কখন রেন্ডার করা উচিত তা নির্ধারণ করার পদ্ধতি৷
def render?
@item.price >= 100
end
এখন, আমরা এগিয়ে যেতে পারি এবং প্রতিটি কোর্স রেন্ডার করে এমন দৃশ্যের মধ্যে ডিসকাউন্ট উপাদান রেন্ডার করতে পারি।
# app/components/course_component.html.erb
<%= render(DiscountComponent.new(item: @item)) %>
এটি নিম্নলিখিত ফল দেয়:
এটা কি অসাধারণ না?
সহায়ক
প্রথাগত রেল ভিউতে, আমরা আমাদের ভিউতে পদ্ধতির নাম কল করে সহজেই আমাদের সাহায্যকারীদের প্লাগ ইন করতে পারি, কিন্তু এটি ভিউ উপাদানগুলির সাথে ভিন্নভাবে কাজ করে। ভিউ কম্পোনেন্টে, হেল্পার মেথড সরাসরি ভিউতে বলা যাবে না কিন্তু একটি কম্পোনেন্টে অন্তর্ভুক্ত করা যেতে পারে। আমাদের ইতিমধ্যেই একটি courses_helper.rb
আছে যে ফাইলটি কোর্স কন্ট্রোলার তৈরি করার সময় স্বয়ংক্রিয়ভাবে তৈরি হয়েছিল, তাই আসুন এটির সুবিধা নেওয়া যাক। প্রথমে, আসুন একটি সহায়ক পদ্ধতি তৈরি করি যা আমাদের জানায় যে এখন পর্যন্ত কতজন লোক একটি কোর্সে ভর্তি হয়েছে। মানটিকে দামের এক চতুর্থাংশ করা যাক :).
module CoursesHelper
def count_enrollees(course)
count = (course.price / 4).round()
tag.p "#{count} enrollees so far"
end
end
এর পরে, আমরা একটি উপাদান তৈরি করব যেখানে আমরা সাহায্যকারীকে কল করব। এটি আমাদের দৃষ্টিতে রেন্ডার করা হবে যে উপাদান. এতে, আমরা একটি include
যোগ করব বিবৃতি, সহকারী সহ, এবং তারপরে আমরা এই উপাদানের মধ্যে সাহায্যকারীর যে কোনও পদ্ধতিকে কল করতে পারি।
# app/components/enrollee_component.rb
class EnrolleeComponent < ViewComponent::Base
include CoursesHelper
def total_enrollees(course)
count_enrollees(course)
end
end
শেষ ধাপটি আমাদের কোর্সগুলি প্রদর্শন করে এমন ভিউতে Enrollee Component যোগ করা।
# app/components/course_component.html.erb
<%= EnrolleeComponent.new.total_enrollees(@item) %>
মনে রাখবেন যে আমরা EnrolleeComponent-এর জন্য রেন্ডার শব্দটি ব্যবহার করছি না, কারণ এটির কোনো ভিউ নেই এবং এর আউটপুট হবে সাহায্যকারী পদ্ধতির মতো। এটি নিম্নলিখিত ফল দেয়:
সাহায্যকারী আইকন, গ্রাভিটার বা আপনি যা বেছে নিতে পারেন তার জন্য ব্যবহার করা যেতে পারে। ভিউ কম্পোনেন্ট সাহায্যকারীদের ব্যবহার পরিবর্তন করে না; এটি কেবল পরিবর্তন করে যে আমরা কীভাবে তাদের আমাদের উপাদানগুলিতে বলি৷
৷পূর্বে_রেন্ডার পদ্ধতি
ViewComponent একটি before_render
অফার করে একটি উপাদান রেন্ডার করার আগে যে পদ্ধতিটি বলা যেতে পারে। আমাদের ডিসকাউন্ট বিজ্ঞপ্তির পাশে একটি তারকা যোগ করা যাক। আমরা একটি সহায়ক পদ্ধতি যোগ করে শুরু করি যা তারকাকে নিয়ে আসে; একটি star.png
ছবি ডাউনলোড করা হয়েছে এবং app/assets/images
-এ রাখা হয়েছে ফোল্ডার।
#app/helpers/courses_helper.rb
def star_icon
image_tag("/assets/star.png", width: "1%")
end
চলুন একটি before_render
যোগ করি আমাদের ডিসকাউন্ট উপাদানের পদ্ধতি যা এই সহায়ক পদ্ধতিকে বলে।
# app/components/discount_component.rb
def before_render
@star_icon = helpers.star_icon
end
আমরা উপরে দেখতে পাচ্ছি, সাহায্যকারীদের কল করার আরেকটি পদ্ধতি চালু করা হয়েছে। helpers.method
ব্যবহার করেও সাহায্যকারীদের ডাকা যেতে পারে component.rb ফাইলে। তারপর, ডিসকাউন্ট কম্পোনেন্টের জন্য আমাদের রেন্ডার পদ্ধতিতে, আমরা আমাদের তারকা আইকন ইনপুট করি, যা এখন @star_icon
এর মাধ্যমে উপলব্ধ করা হয়েছে পরিবর্তনশীল।
# app/components/discount_component.html.erb
<p class="green"> <%= @star_icon %> A 10% discount is available on this course </p>
এটি নিম্নলিখিত ফল দেয়:
before_render
-এর জন্য আমাদের অগত্যা সাহায্যকারী ব্যবহার করতে হবে না কাজ করার পদ্ধতি। আমি সাহায্যকারী ব্যবহার করেছি কলিং হেল্পার পদ্ধতিতে অন্য পদ্ধতির প্রবর্তন করতে।
প্রিভিউ
অ্যাকশন মেইলারের মতো, ভিউ কম্পোনেন্ট উপাদানগুলির পূর্বরূপ দেখা সম্ভব করে তোলে। এটি প্রথমে config/application.rb
এ সক্ষম করতে হবে ফাইল।
config.view_component.preview_paths << "#{Rails.root}/lib/component_previews"
প্রিভিউ উপাদানগুলি test/components/previews
-এ অবস্থিত এবং বিভিন্ন ধরনের ইনপুট দিয়ে একটি উপাদানের পূর্বরূপ দেখতে ব্যবহার করা যেতে পারে। আমরা আমাদের ডিসকাউন্ট কম্পোনেন্টের পূর্বরূপ দেখব।
# test/components/previews/discount_component_preview.rb
class DiscountComponentPreview < ViewComponent::Preview
def with_first_course
render(DiscountComponent.new(item: Course.find(1)))
end
def with_second_course
render(DiscountComponent.new(item: Course.find(2)))
end
end
বিভিন্ন পরিস্থিতিতে ডিসকাউন্ট কম্পোনেন্টের পূর্বরূপ দেখতে দুটি পদ্ধতি যোগ করা হয়েছে। এটি দেখতে, https://localhost:3000/rails/view_components
এ যান , যেখানে আমরা তৈরি করা সমস্ত পূর্বরূপ উপাদান এবং তাদের পদ্ধতিগুলি খুঁজে পাই। নীচে দেখানো হিসাবে, তারা কেমন দেখাচ্ছে তা দেখতে আমরা তাদের যেকোনোটিতে ক্লিক করতে পারি৷
আপনি উপরের ভিডিওতে দেখতে পাচ্ছেন, প্রথম কোর্সটি ডিসকাউন্ট উপাদান রেন্ডার করে, কিন্তু দ্বিতীয় কোর্সের জন্য কিছুই রেন্ডার করা হয় না। কেন এমন হয়েছে জানেন? render?
পদ্ধতি চেক ঘটেছে। প্রথম দৃশ্য হল যখন খরচ মূল্য 100 ইউরোর বেশি (1ম কোর্স), কিন্তু দ্বিতীয় কোর্সের জন্য খরচ 100 ইউরোর কম। পদ্ধতির নামগুলি এখানে হাইলাইট করার আগে আপনাকে কারণটি বের করতে সক্ষম করার জন্য আরও বর্ণনামূলক ছিল না :)।
show_previews
ব্যবহার করে যেকোন পরিবেশে পূর্বরূপ সক্রিয় বা নিষ্ক্রিয় করা যেতে পারে বিকল্প, কিন্তু বিকাশ এবং পরীক্ষার পরিবেশে, এগুলি ডিফল্টরূপে সক্রিয় থাকে৷
# config/environments/test.rb
config.view_component.show_previews = false
JS এবং CSS অন্তর্ভুক্তি
উপাদানগুলির পাশাপাশি JavaScript এবং CSS অন্তর্ভুক্ত করা সম্ভব, কখনও কখনও "sidecar" সম্পদ বা ফাইল বলা হয়। এটি এখনও একটি পরীক্ষামূলক বৈশিষ্ট্য। তাই, আমরা এই নিবন্ধে এর অভ্যন্তরীণ কার্যকারিতাগুলিতে ডুব দেব না, তবে আপনি এখানে এই ভিউ কম্পোনেন্ট বৈশিষ্ট্য সম্পর্কে আরও জানতে পারেন৷
টেমপ্লেট
একটি ভিউ উপাদানের টেমপ্লেট বিভিন্ন উপায়ে সংজ্ঞায়িত করা যেতে পারে। সহজ বিকল্প হল একই ফোল্ডারে ভিউ এবং কম্পোনেন্ট ঢোকানো, যেমনটি নীচে দেখানো হয়েছে।
আমরা এখানে দেখতে পাচ্ছি, app/components
-এ আমাদের প্রতিটি কম্পোনেন্ট এবং ভিউ আছে ফোল্ডার।
আরেকটি বিকল্প হল কম্পোনেন্টের মতো একই নামের একটি সাবডিরেক্টরিতে ভিউ এবং অন্যান্য সম্পদ স্থাপন করা। এইভাবে, app/components
-এ ফোল্ডার, আমাদের component.rb
আছে ফাইল, যেটিতে কম্পোনেন্ট থাকে এবং তারপর একটি আলাদা course_component
ফোল্ডার, যেখানে course_component.html.erb
ভিউ থাকে এবং কোর্স_কম্পোনেন্ট সম্পর্কিত প্রতিটি অন্যান্য সম্পদ।
কমান্ড লাইন থেকে এইভাবে কম্পোনেন্ট ফাইল তৈরি করতে, --sidecar
পতাকা প্রয়োজন:
rails g component Example name --sidecar
এটি আপনাকে আপনার css এবং js ফাইলগুলিকে কম্পোনেন্ট ফোল্ডারে যোগ করতে সক্ষম করে৷ ViewComponents একটি call
সংজ্ঞায়িত করে একটি টেমপ্লেট ফাইল ছাড়াই রেন্ডার করতে পারে৷ পদ্ধতি এর একটি উদাহরণ পরবর্তী বিভাগে দেওয়া হয়েছে, যেখানে আমরা স্লট নিয়ে আলোচনা করব .
স্লট
স্লট ব্যবহার করে একক ভিউ কম্পোনেন্টে কন্টেন্টের একাধিক ব্লক পাঠানো যেতে পারে . has_one
এর অনুরূপ এবং has_many
রেল মডেলের বৈশিষ্ট্য, স্লট renders_one
দিয়ে সংজ্ঞায়িত করা হয় এবং renders_many
:
- renders_one একটি স্লট সংজ্ঞায়িত করে যা প্রতি কম্পোনেন্টে সর্বাধিক একবার রেন্ডার করা হবে:renders_one :header।
- renders_many একটি স্লট সংজ্ঞায়িত করে যা প্রতি-কম্পোনেন্টে একাধিকবার রেন্ডার করা যেতে পারে:renders_many :titles।
কল্পনা করুন যে আমরা এমন একটি পৃষ্ঠা রাখতে চাই যা একটি শিরোনাম এবং আমাদের উপলব্ধ সমস্ত কোর্সের শিরোনাম রেন্ডার করে; এটি স্লট ব্যবহার করে অর্জন করা যেতে পারে . আসুন একটি লিস্ট কম্পোনেন্ট তৈরি করি , যাতে একটি শিরোনাম থাকবে যা শুধুমাত্র একবার রেন্ডার করা হয় এবং একটি TitleComponent , যা অনেক টাইটেল রেন্ডার করে।
#app/components/list_component.rb
class ListComponent < ViewComponent::Base
renders_one :header, "HeaderComponent"
# `HeaderComponent` is defined within this component, so we refer to it using a string.
renders_many :titles, TitleComponent
# `titleComponent` will be defined in another file, so we can refer to it by class name.
class HeaderComponent < ViewComponent::Base
def call
content_tag :h1, content
end
end
end
উপরের উপাদানে, আমরা বলেছি যে শিরোনামটি একবার রেন্ডার করা হয়, কিন্তু শিরোনামগুলি অনেকবার রেন্ডার করা হয়, কারণ এই পৃষ্ঠাটিতে অনেকগুলি শিরোনাম থাকবে৷ আমরা লিস্ট কম্পোনেন্টের মধ্যে হেডার কম্পোনেন্টকেও সংজ্ঞায়িত করেছি। হ্যাঁ, এটি ViewComponent দিয়ে সম্ভব; একটি শ্রেণী অন্য শ্রেণীর মধ্যে সংজ্ঞায়িত করা যেতে পারে। আসুন টেমপ্লেট বিভাগের অধীনে আগে আলোচিত কল পদ্ধতি এবং একটি h1 ট্যাগ রেন্ডার করার জন্য কীভাবে এটি হেডার কম্পোনেন্টে ব্যবহার করা হচ্ছে তাও নোট করা যাক, যার ফলে একটি সংশ্লিষ্ট ভিউ (html.erb ফাইল) এর প্রয়োজনীয়তা দূর হয়। ListComponent-এর জন্য সংশ্লিষ্ট HTML ফাইলে নিম্নলিখিতগুলি থাকবে;
#app/components/list_component.html.erb
<div>
<%= header %> <!-- renders the header component -->
<% titles.each do |title| %>
<div>
<%= title %> <!-- renders an individual course title -->
</div>
<% end %>
</div>
html ফাইলে, আমরা শিরোনামটি অন্তর্ভুক্ত করেছি, কম্পোনেন্টে পাস করা সমস্ত শিরোনামের মাধ্যমে পুনরাবৃত্তি করেছি এবং সেগুলিকে রেন্ডার করেছি। আপনি দেখতে পাচ্ছেন, লিস্ট ভিউ ফাইলে রেন্ডার করার জন্য আমাদেরকে কম্পোনেন্টের নাম উল্লেখ করতে হবে না; আমাদের স্লট যে যত্ন নিয়েছে. তাই, আমরা তাদের শুধু header
হিসেবে চিহ্নিত করি এবং title
.
পরবর্তী পদক্ষেপটি হল আমাদের টাইটেল কম্পোনেন্ট এবং এর সংশ্লিষ্ট HTML ফাইল তৈরি করা, কারণ এটি পাস করা প্রতিটি শিরোনামের জন্য রেন্ডার করা হবে৷
# app/components/title_component.rb
class TitleComponent < ViewComponent::Base
def initialize(title:)
@title = title
end
end
# app/components/title_component.html.erb
<div>
<h3> <%= @title %> </h3>
</div>
অবশেষে, আমাদের index.html
-এ ফাইল, আমাদের যা আছে তা সাময়িকভাবে মুছে ফেলি এবং ListComponent রেন্ডার দিয়ে প্রতিস্থাপন করি।
#app/views/courses/index.html.erb
<%= render ListComponent.new do |c| %>
<% c.header do %>
<%= link_to "List of Available Courses", root_path %>
<% end %>
<%= c.title(title: "First title") %>
<%= c.title(title: "Second title!") %>
<% end %>
এখন, আসুন আমাদের কোর্সগুলিকে এই ভিউতে একটি সংগ্রহ হিসাবে পাস করি। একটি স্লটে একটি সংগ্রহ পাস করার জন্য, আমরা শুরু করার জন্য প্রয়োজনীয় ভেরিয়েবল ধারণকারী বস্তুর অ্যারে হিসাবে সংগ্রহটি পাস করতে হবে। আমরা দেখতে পাচ্ছি, পাস করা প্রতিটি কোর্স শিরোনাম যুক্তি দিয়ে শুরু করা উচিত। আমরা আমাদের ডিবি-তে সমস্ত কোর্সের শিরোনামগুলিকে হ্যাশের একটি অ্যারেতে বের করতে পারি এবং এটি রেন্ডার করতে পারি।
আমরা এখন আমাদের একাধিক শিরোনামের তালিকাকে একটি c.titles
দিয়ে প্রতিস্থাপন করতে পারি একটি সংগ্রহের জন্য এবং এটিকে আমাদের শিরোনামগুলির হ্যাশে প্রেরণ করুন, যা আমরা পরিবর্তনশীল course_titles
ব্যবহার করে সংজ্ঞায়িত করি .
# app/views/courses/index.html.erb
<% course_titles = Course.all.pluck(:title).map { |title| {title: title}} %>
<% c.titles(course_titles) %>
এটি নিম্নলিখিত ফল দেয়:
স্লটগুলি ঠিক এইভাবে কাজ করে:একটি একক ভিউ কম্পোনেন্টের মধ্যে বেশ কয়েকটি উপাদান রেন্ডার করা। স্লটগুলি অন্যান্য বিভিন্ন উপায়ে রেন্ডার করা যেতে পারে এবং আপনি এখানে আরও তথ্য পেতে পারেন৷
৷পরীক্ষা
পরীক্ষার ফাইলে "view_component/test_case" প্রয়োজন এবং render_inline
ব্যবহার করে ভিউ উপাদান পরীক্ষা করা হয় পরীক্ষার সাহায্যকারী যাতে রেন্ডার করা আউটপুটের বিরুদ্ধে দাবী করা হয়। আমাদের ডিসকাউন্ট কম্পোনেন্ট পরীক্ষা করে শুরু করা যাক।
require "test_helper"
require "view_component/test_case"
class DiscountComponentTest < ViewComponent::TestCase
def test_render_component
render_inline(DiscountComponent.new(item: "my item"))
end
end
যখন আমরা rails test test/components/discount_component_test.rb
কমান্ড ব্যবহার করে এই পরীক্ষাটি চালাই , আমরা নিম্নলিখিত ত্রুটি পাই:
এটি আমাদের কাছে প্রমাণ করে যে পরীক্ষাটি সঠিক উপাদানে পৌঁছেছে কিন্তু একটি উপযুক্ত প্রপের অভাব রয়েছে, কারণ আইটেমটি অবশ্যই মূল্য সম্পত্তি সহ একটি কোর্স হতে হবে এবং একটি স্ট্রিং নয়, যেমন আমরা পাস করেছি৷ এটি আমাদেরকেও বলে যে একটি render?
আছে এই উপাদান রেন্ডার করার আগে পদ্ধতি পরীক্ষা করা হচ্ছে। এখন সঠিক ভেরিয়েবলে পাস করা যাক।
def test_render_component
course = Course.create(title: 'Organizing your Time', price: 55.00, location: 'London')
render_inline(DiscountComponent.new(item: course))
end
এই সফলভাবে সঞ্চালিত হয়. আসুন এই পরীক্ষায় দাবী যোগ করতে এগিয়ে যাই।
def test_render_component
course = Course.create(title: 'Organizing your Time', price: 155.00, location: 'London')
render_inline(DiscountComponent.new(item: course))
assert_selector 'p[class="green"]'
assert_text "10% discount"
end
এই পরীক্ষাটিও পাস করে৷ স্মরণ করুন যে এই উপাদানটির জন্য একটি রেন্ডার শর্ত রয়েছে৷ চিন্তা করবেন না, যদিও, কারণ ViewComponent এছাড়াও refute_component_rendered
ব্যবহার করে একটি কম্পোনেন্ট রেন্ডার করা হয়নি তা পরীক্ষা করার একটি উপায় প্রদান করে . আমরা 100 ইউরোর নিচে মূল্য সহ একটি কোর্স ব্যবহার করে এটি পরীক্ষা করতে পারি।
def test_component_not_rendered
course = Course.create(title: 'Organizing your Time', price: 55.00, location: 'London')
render_inline(DiscountComponent.new(item: course))
refute_component_rendered
end
এই পরীক্ষাটিও পাস করে।
আসুন আমাদের কোর্স কম্পোনেন্টের জন্য আরেকটি পরীক্ষা লিখি যে এটি এর মধ্যে থাকা সমস্ত উপাদানকে রেন্ডার করে।
require "test_helper"
require "view_component/test_case"
class CourseComponentTest < ViewComponent::TestCase
def test_component_renders_all_children
course = Course.create(title: 'Organizing your Time', price: 155.00, location: 'London')
render_inline(CourseComponent.new(item: course, notice: 'A new test', item_counter: 1))
assert_selector("h2", text: "Organizing your Time")
assert_selector("h4", text: "€155.00")
assert_selector("h4", text: "London")
assert_text("enrollees")
assert_text("discount")
end
end
এই পরীক্ষাও পাস করে। এটি পরীক্ষা করে যে তালিকাভুক্ত এবং ডিসকাউন্ট উপাদানগুলিও সঠিকভাবে রেন্ডার করছে৷
মনে রাখবেন যে আমাদের একটি স্লট উপাদান রয়েছে এবং নীচের ছবিতে দেখানো হয়েছে, এটি একটি শিরোনাম এবং অনেকগুলি শিরোনাম রেন্ডার করে৷
এটি পরীক্ষা করার জন্য, আমরা কম্পোনেন্টটিকে হেডার এবং শিরোনাম সমন্বিত কোডের একটি ব্লক পাস করি যা এটি রেন্ডার করা উচিত এবং তারপর আমরা রেন্ডার করা উপাদানটির বিরুদ্ধে জোর দিতে পারি।
require "test_helper"
require "view_component/test_case"
class ListComponentTest < ViewComponent::TestCase
def test_renders_slots_with_content
render_inline(ListComponent.new) do |component|
component.header { "A Test List" }
component.titles [{title: 'Test title 1'}, {title: 'Test title 2'}]
end
assert_selector("h1", text: "A Test List")
assert_text("Test title 1")
assert_text("Test title 2")
end
end
এই পরীক্ষাটিও পাস করে :).
Rspec পরীক্ষা
টেস্টিং সম্পর্কে উপরে যা বলা হয়েছে তার পাশাপাশি, পছন্দের টেস্টিং ফ্রেমওয়ার্ক যদি RSpec হয়, তাহলে ViewComponents-এর জন্য RSpec সক্ষম করতে কিছু অতিরিক্ত কনফিগারেশন করতে হবে।
# spec/rails_helper.rb
require "view_component/test_helpers"
require "capybara/rspec"
RSpec.configure do |config|
config.include ViewComponent::TestHelpers, type: :component
config.include Capybara::RSpecMatchers, type: :component
end
আমাদের ডিসকাউন্ট কম্পোনেন্ট পরীক্ষাটি পুনরায় লেখা এবং পুনরায় পরীক্ষা করা যেতে পারে Rspec ব্যবহার করে, নীচে দেখানো হয়েছে:
require "rails_helper"
RSpec.describe DiscountComponent, type: :component do
it "renders the component correctly" do
course = Course.create(title: 'Organizing your Time', price: 155.00, location: 'London')
render_inline(DiscountComponent.new(item: course))
expect(rendered_component).to have_css "p[class='green']", text: "10% discount"
expect(rendered_component).to have_css "img[src*='/assets/star.png']"
end
end
এই পরীক্ষা মার্জিতভাবে পাস. হেল হ্যাঁ, আমরা আমাদের তারকা আইকন দেখতে পাচ্ছি।
উপসংহার
আপনার Rails অ্যাপ্লিকেশানের জন্য বেশ কয়েকটি ভিউ উপাদান লেখার ফলে আপনার কোডকে আরও পাঠযোগ্য এবং অবাঞ্ছিত জটিলতা থেকে ত্রুটির প্রবণতা কম হয় না বরং এটি শুধুমাত্র HTTP অনুরোধের সময়ই নয় বরং আপনার মতামতকে বিচ্ছিন্নভাবে পরীক্ষা করাও সম্ভব করে তোলে। ভিউ কম্পোনেন্টগুলি একটি বিদ্যমান রেল অ্যাপে প্রবেশ করানো সহজ, এবং বেশিরভাগই পুনঃব্যবহৃত ভিউ দিয়ে শুরু করা সবচেয়ে ভালো। এখন পর্যন্ত যা কিছু শিখেছি তার সাথে, এটি একটি সহজ-শান্তির কাজ হওয়া উচিত। তবুও, আপনি যদি ভিউ কম্পোনেন্ট সম্পর্কে আরও তথ্য চান, তাহলে এর ডকুমেন্টেশন বা রুবিডক তথ্যের মাধ্যমে যেতে দ্বিধা করবেন না।