RENDER PARTIALS IN RAILS
1. Tổng quan Partials: cho phép bạn dễ dàng trong việc organize (tổ chức) và reuse (tái sử dụng) lại view code trong ứng dụng Rails. Vậy dấu hiêụ nào để bạn nhận biết file đó là partial?? Tên file partial điển hình được bắt đầu với 1 dấu gạch dưới (_) và kết thúc bằng đuôi mở rộng ...
1. Tổng quan
- Partials: cho phép bạn dễ dàng trong việc organize (tổ chức) và reuse (tái sử dụng) lại view code trong ứng dụng Rails. Vậy dấu hiêụ nào để bạn nhận biết file đó là partial??
- Tên file partial điển hình được bắt đầu với 1 dấu gạch dưới (_) và kết thúc bằng đuôi mở rộng .html.erb như trong views của bạn.
- Ví dụ:
1, 1 model: models/user.rb
class User < ActiveRecord::Base end
2, 1 controller: controllers/user_controller.rb có 2 action: new, edit
class UsersController < ApplicationController def new end def edit end end
3, 1 folder: views/users/ có 2 file views: new.html.erb, edit.html.erb. Theo cách thông thường: bạn tạo 2 file view và nội dung trong 2 file này tương tự nhau:
# Trong file new.html.erb <div class="row"> <%= form_for @user do |f| %> <%= f.label :name %> <%= f.text_field :name, class: "form-control" %> <%= f.label :email %> <%= f.email_field :email, class: "form-control" %> <%= f.label :password %> <%= f.password_field :password, class: "form-control" %> <%= f.label :password_confirmation %> <%= f.password_field :password_confirmation, class: "form-control" %> <%= f.submit, class: "btn btn-primary" %> <% end %> </div>
Và:
# Trong file edit.html.erb <div class="row"> <%= form_for @user do |f| %> <%= f.label :name %> <%= f.text_field :name, class: "form-control" %> <%= f.label :email %> <%= f.email_field :email, class: "form-control" %> <%= f.label :password %> <%= f.password_field :password, class: "form-control" %> <%= f.label :password_confirmation %> <%= f.password_field :password_confirmation, class: "form-control" %> <%= f.submit, class: "btn btn-primary" %> <% end %> </div>
Tuy nhiên việc sử dụng những đoạn code này bị lặp lại, vậy giải pháp đưa ra ở đây là:
Sử dụng file partial: _form.html.erb
<%= form_for @user do |f| %> <%= f.label :name %> <%= f.text_field :name, class: "form-control" %> <%= f.label :email %> <%= f.email_field :email, class: "form-control" %> <%= f.label :password %> <%= f.password_field :password, class: "form-control" %> <%= f.label :password_confirmation %> <%= f.password_field :password_confirmation, class: "form-control" %> <%= f.submit, class: "btn btn-primary" %> <% end %>
Tiếp theo, trong 2 file new.html.erb và edit.html.erb ta chỉ việc render ra nó:
# Trong file new.html.erb <div class="row"> # Thay vì sử dụng cấu trúc đầy đủ <%= render partial: "form" %> thì ta dùng: <%= render "form" %> </div> # Trong file edit.html.erb <div class="row"> <%= render "form" %> </div>
2. Rendering partials
- Partial rendering trong 1 controller phổ biến nhất được sử dụng cùng với ajax maf chỉ cập nhật một hoặc một số các phần tử trên 1 trang mà không phải reloading
- Ví dụ:
# app/controllers/users_controller.rb def index @users = User.all end
# app/views/_user.html.erb # _user.html.erb là file partial <h1><%= user.name %></h1> # app/views/users/index.html.erb <% @users.each do |user| %> <%= render partial: "user", locals: {user: user} %> <% end %>
2.1. :as và :object options
- Mặc định thì ActionView::PartialRenderer không có bất kỳ biến local nào. :object option có thể được sử dụng để tạo ra một object trong partial:
# :object option <%= render partial: "account", object: @buyer %> # Tương đương với <%= render partial: "account", locals: {account: @buyer} %> # Với :as option, chúng ta có thể đặc tả một tên khác cho biến local # Ví dụ chúng ta muốn sử dụng tên là user thay vì account <%= render partial: "account", object: @buyer, as: "user" %> # Điều này tương đương với: <%= render partial: "account", locals: {user: @buyer} %>
2.2. Rendering a collection of partials
# Render một tâp các partial giống nhau bằng việc tạo ra mỗi phần tử của biến @winners thông qua biến local "person" <%= render partial: "person", collection: @winners %> # Render một tập các partial nhưng custom tên biến local <%= render partial: "admin_person", collection: @winners, as: :person %> # Render một tập các partial giống nhau, nhưng cũng render person_divider partial giữa mỗi person partial <%= render partial: "person", collection: @winners, spacer_template: "person_divider" %> # Trường hợp :collection là nil hoặc empty, render sẽ trả về nil # Điều này sẽ cho phép bạn đặc tả một dòng text, dòng text này sẽ được hiển thị thay vì: <%= render(partial: "person", collection: @winners) || "There's no person to be displayed" %>
2.3. Rendering trường hợp mặc định
- Nếu bạn không sử dụng bất kỳ options nào như là collections hay layouts, bạn có thể sử dụng cấu trúc short-hand mặc định của render để render partials
- Ví dụ:
# Thay vì dùng: <%= render partial: "account" %> thì sử dụng: <%= render "account" %> # Thay vì: <%= render partial: "account", locals: {account: @buyer} %> <%= render "account", account: @buyer %> # Thay vì: <%= render partial: "accounts/account", locals: {account: @account} %> <%= render @account %> # Thay vì: <%= render partial: "posts/post", collection: @posts %> <%= render @posts %>
Trên đây là một số cấu trúc short-hand mà bạn có thể sử dụng thay thế cho cấu trúc đầy đủ mặc định. Khi các bạn đã sử dụng quen thì có thể dùng cấu trúc rút gọn của nó để dòng code được clear hơn.
3. Kết luận
Trên đây tôi đã giới thiêu sơ lược về Render partial in Rails và cách sử dụng nó trong các trường hợp cụ thể. Hy vọng bài viết giúp các bạn có cái nhìn tổng quát hơn về cách sử dụng partial trong Rails và áp dụng nó vào trong Rails app của bạn.
Cảm ơn bạn đã theo dõi!
Link tài liệu:
- http://api.rubyonrails.org/classes/ActionView/PartialRenderer.html
- http://apidock.com/rails/ActionController/Base/render