Sử dụng content_for để Refactor view
1. Giới thiệu Trong layout của bạn có những đoạn code html, css hay js dài loằng ngoằng... được lặp đi lặp lạivà việc viêt đi viết lại đoạn code này khiến bạn thấy nhàm chán, khiến cho code của bạn ko đc clear... và bạn đang tìm một cách nào đó tối ưu hơn để khắc phục vấn đề này. Thì hôm nay, ...
1. Giới thiệu
- Trong layout của bạn có những đoạn code html, css hay js dài loằng ngoằng... được lặp đi lặp lạivà việc viêt đi viết lại đoạn code này khiến bạn thấy nhàm chán, khiến cho code của bạn ko đc clear... và bạn đang tìm một cách nào đó tối ưu hơn để khắc phục vấn đề này. Thì hôm nay, mình sẽ giới thiệu cho các bạn một phương pháp để giải quyết vấn đề này. Đó là sử dụng content_for đây là một method củaActionView.
- content_for được sử dụng để đánh dấu một khối các câu lệnh (html, javascript hay css ...) vào một định danh để lưu lại phục vụ cho việc sử dụng sau này.
- Để truy cập và lấy nội dung đã được lưu trữ để sử dụng trong các templetes, helper modules hay trong các layout, bạn chỉ cần đưa định danh mà bạn đã đặt vào trong content_for như một argument
2. Khai báo:
content_for(name, content = nil, options = {}, &block) ví dụ:
<% content_for :dinh_danh do %> <<khối lệnh>> <% end %>
3. Sử dụng
Sau khi khai báo thì ta chỉ cần chuyền định danh ta đã khai báo vào để lấy ra sử dụng ta có thể dùng theo các cách sau:
-
Cách gọi:
<%= content_for :dinh_danh %>
Câu lệnh trên tương đương với câu lệnh sau:
<%= yield :dinh_danh %>
-
Sử dụng trong module helper
module HeaderHelper def display_header content_for(:header) || "Header default" end end
Với cách dùng trên, khi ta gọi hàm <% display_header %> mà content_for :header chưa được định nghĩa thì display_header sẽ lấy giá trị mặc định là "Header default".
-
Cách chèn mã css/javascript cho những trang cụ thể bạn muốn chèn, còn những trang khác thì không. Cách làm mình như sau:
-
Mình sẽ đặt tên indentifier specific_page_css, và specific_page_js chung cho các định danh content_for cho mã css và mã javascript và đặt vào trong layouts/application.html.erb như sau:
<html> <head> <META http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Hướng dẫn sử dụng content_for</title> <%= content_for :specific_page_css %> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <%= yield %> </div> <%= content_for :specific_page_js %> </body> </html>
(thông thường mã css sẽ đc đặt trên đầu còn js đặt ở phía dưới nên mình để vào theo cấu trúc như vậy để tiện quản lý) Bạn cũng có thể khai báo với tên khác cho từng khối css/js bạn muốn chèn và gọi vào ở trong view tuy nhiên theo mình thấy thì sử dụng theo cách của mình sẽ đỡ tốn thời gian khai báo lại chỗ sử dụng, lúc này chỉ cần vào trang nào muốn chèn css/js vào thì chỉ cần nghĩa khối content_for là xong, và khi không có định nghĩa thì nó sẽ tự động nhận giá trị nil.
-
Tiếp theo muốn sử dụng ở trang nào thì mình chỉ cần định nghĩa khốicontent_for :specific_page_csshay :specific_page_js mình muốn chèn vào. Ví dụ. tại trang show.html.erb muốn chèn vào css là một đoạn css được định nghĩa trong assets/stylesheets/custom.scss và js muốn truyền vào là một đoạn js được định nghĩa trong assets/javascripts/custom.js. Thì ta định:
<% content_for :specific_page_css do %> <%= stylesheet_link_tag :custom %> <% end %> <h1> Show page </h1> <% content_for :specific_page_js do %> <%= javascript_include_tag :custom %> <% end %>
kết quả thu được:
<html> <head> <META http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Hướng dẫn sử dụng content_for</title> <<nội dung css trong file custom.scss >> </head> <body class="hold-transition skin-blue sidebar-mini"> <div class="wrapper"> <h1> Show page </h1> </div> <<nội dung js trong file custom.js>> </body> </html>
-
4. Kết luận
Trên đây mình đã giới thiệu cho các bạn về 1 cách cơ bản để Refactor vew bằng cách sử dụng content_for. các bạn có thể tìm hiểu hem tại đây