Rails – Tùy chỉnh View


Được đăng vào ngày 07/11/2016 | 0 bình luận
Rails – Tùy chỉnh View
5 (100%) 1 vote

Chúng ta sẽ chỉnh sửa giao diện người dùng (View) với ứng dụng depot đã làm trong bài trước.

Tạo dữ liệu với seeds.rb

Trước tiên chúng ta sẽ cần đến một số dữ liệu mẫu để sử dụng. Nếu bạn còn nhớ thì trong bài trước chúng ta biết là Rails sẽ tạo sẵn một form để chúng ta thực hiện thêm bản ghi vào model rất dễ dàng. Tuy nhiên việc ngồi gõ từng dòng dữ liệu như thế rất chán và mệt mỏi, do đó Rails cung cấp cho chúng ta một cách tạo dữ liệu khác.

Ở trong thư mục db có một file có tên là seeds.rb, đây là file Rails dành cho chúng ta để ghi đoạn code tạo đối tượng từ model, và Rails sẽ đọc các dòng code đó rồi insert thành các bản ghi trong CSDL luôn. Ví dụ chúng ta mở file này ra rồi chèn vào đoạn code sau:

# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)
Product.delete_all
Product.create(:title => 'Learn Web Development with Rails',
    :description => 
    %{
        Ruby on Rails Tutorial book and screencast series 
        teach you how to develop and deploy real, 
        industrial-strength web applications with Ruby on Rails.
    },
    :image_url => 'rails_book.png',
    :price => 29.99)
 
Product.create(:title => 'The Ruby Programming Language',
    :description =>
    %{
        The Ruby Programming Language is the authoritative guide 
        to Ruby and provides comprehensive coverage 
        of versions 1.8 and 1.9 of the language.
    },
    :image_url => 'ruby_book.png',
    :price => 39.99)

Trong đoạn code trên chúng ta tạo 2 đối tượng Product. Dòng đầu tiên chúng ta gọi phương thức delete_all, phương thức này sẽ xóa toàn bộ bản ghi có trong CSDL, tiếp theo chúng ta gọi phương thức create và đưa vào các tham số dữ liệu để tạo mới đối tượng. Có một lưu ý là trong thuộc tính description chúng ta dùng cú pháp %{...}, cú pháp này cho phép chúng ta ghi chuỗi trên nhiều dòng, thay vì truyền vào trong dấu nháy kép thì phải nối chuỗi.

Sau đó để thực hiện việc tạo các bản ghi này trong CSDL thì chúng ta mở command prompt lên rồi gõ lệnh rake db:seed là được.

C:\Project\Rails\depot>rake db:seed

Bạn có thể chạy server rồi trỏ đến URL /products hoặc dùng trình sqlite3 để kiểm tra nội dung trong CSDL đã được chèn vào hay chưa, tất nhiên là chẳng có gì đặc biệt cả.

Tùy chỉnh View

Trước tiên chúng ta tìm hiểu sơ qua về khái niệm Layout. Layout ở đây có nghĩa là một đoạn code được dựng sẵn để dùng chung cho toàn bộ website, các trang View khác trong website sẽ copy code trong layout vào code của chính nó rồi chèn thêm các đoạn code đặc trưng của nó vào. Vậy đoạn code layout dùng chung đó nằm ở đâu? câu trả lời la file application.html.erb trong thư mục app/views/layouts, file này được Rails tạo ra tự động và có nội dung như sau:

<!DOCTYPE html>
<html>
<head>
    <title>Depot</title>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>
</head>
<body>

<%= yield %>

</body>
</html>

Chúng ta sẽ tìm hiểu về layout sau, ở đây chúng ta chỉ cần để ý các đoạn nằm trong thẻ <%= %>. Các đoạn code nằm trong cặp thẻ này được gọi chung là template, chúng ta có thể gọi một số hàm, thực hiện một số câu lệnh đơn giản như if, vòng lặp… hoặc tham chiếu đến biến trong cặp thẻ này… và những gì nằm trong cặp thẻ này sẽ được trình biên dịch Rails dịch ra thành code HTML rồi chèn vào đó. Ở đây dòng:

<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>

có nghĩa là tạo các thẻ <link> trỏ đến toàn bộ file CSS có trong thư mục app/assets/stylesheets, bạn có thể mở thư mục này ra và thấy trong đó có sẵn một số file CSS do Rails tự tạo ra rồi, một số file có thể có đuôi .scss, nhưng cũng không quan trọng mấy.

Tương tự, các file Javascript và các file ảnh sẽ được đặt vào trong thư mục app/assets/javascriptsapp/assets/images.

Bây giờ chúng ta tạo một file có tên depot.css chứa nội dung như sau:

#product_list table tr td {
    padding: 5px;
    vertical-align: top;
}

#product_list .list_image {
    width: 60px;
    height: 70px;
}

#product_list .list_description {
    width: 60%;
}

#product_list .list_description dl {
    margin: 0;
}

#product_list .list_description dt {
    color: #244;
    font-weight: bold;
    font-size: larger;
}

#product_list .list_description dd {
    margin: 0;
}

#product_list .list_actions {
    font-size: x-small;
    text-align: right;
    padding-left: 1em;
}

#product_list .list_line_even {
    background: #e0f8f8;
}

#product_list .list_line_odd {
   background: #f8b0f8;
}

#store .entry {
    overflow: auto;
    margin-top: 1em;
    border-bottom: 1px dotted #77d;
}

#store .title {
    font-size: 120%;
    font-family: sans-serif;
}

#store .entry img {
    width: 80px;
    margin-right: 5px;
    margin-bottom: 5px;
    float: left;
}


#store .entry h3 {
    margin-top: 0;
    margin-bottom: 2px;
    color: #227;
}

#store .entry p {
    margin-top: 0.5em; 
    margin-bottom: 0.8em; 
}

#store .entry .price_line {
    clear: both;
    margin-bottom: 0.5em;
}

#store .entry .add_to_cart {
    position: relative;
}

#store .entry .price {
    color: #44a;
    font-weight: bold;
    margin-right: 2em;
}

Chúng ta định nghĩa vài class CSS đơn giản để hiển thị trang /products theo giao diện mới một tí. Và tất nhiên file này sẽ được file layout tham chiếu tới như đã nói ở trên.

Tiếp theo chúng ta sửa lại file index.html.erb trong thư mục app/views/products như sau:

<div id="product_list">
    <h1>Products</h1>
 
    <table>
    <% @products.each do |product| %>
        <tr class="<%= cycle('list_line_odd', 'list_line_even') %>">
 
            <td>
                <%= image_tag(product.image_url, :class => 'list_image') %>
            </td>
 
            <td class="list_description">
                <dl>
                    <dt><%= product.title %></dt>
                    <dd><%= truncate(strip_tags(product.description),
                            :length => 80) %></dd>
                </dl>
            </td>
 
            <td class="list_actions">
                <%= link_to 'Show', product %><br/>
                <%= link_to 'Edit', edit_product_path(product) %><br/>
                <%= link_to 'Destroy', product, 
                    data: { confirm: 'Are you sure?' },
                    :method => :delete %>
            </td>
        </tr>
    <% end %>
    </table>
</div>

<br />

<%= link_to 'New product', new_product_path %>

Có một số điểm lưu ý trong đoạn code trên như sau:

  • Hàm cycle() có tác dụng duyệt qua lần lượt từng phần tử trong danh sách, khi đến hết danh sách thì lại quay về phần tử đầu tiên, trong ví dụ trên thì class của thẻ tr đầu tiên sẽ là list_line_odd hoặc list_line_even tùy vào từng lần lặp.
  • Hàm truncate() có tác dụng lấy một lượng kí tự nhất định, ở đây chúng ta lấy 80 kí tự, ngoài ra chúng ta còn dùng hàm strip_tags() để loại bỏ các thẻ HTML trong chuỗi cho trước.
  • Các dòng link_to <tên phương thức>  chẳng hạn như link_to 'Destroy' có nghĩa là gọi đến phương thức destroy trong file controller, tức là file app/controllers/products_controller.rb, ngoài ra theo sau chúng ta còn có thể truyền vào các tham số, ví dụ như data: { confirm: 'Are you sure?'} tức là truyền vào đối tượng data có thuộc tính confirm có giá trị là chuỗi "Are you sure?" (dưới dạng JSON). Dòng này sẽ được Rails dịch thành thuộc tính data-confirm trong thẻ <a>, nếu bạn rành HTML5 thì bạn sẽ biết là thuộc tính này sẽ tạo một hộp thoại để xác nhận.

Bây giờ bạn có thể chạy server và trỏ đến localhost:3000/products để xem giao diện mới.

capture







Trả lời


Lưu ý: bọc code trong cặp thẻ [code language="x"][/code] để highlight code.


Ví dụ:


[code language="cpp"]


    std::cout << "Hello world";


[/code]



Các ngôn ngữ được hỗ trợ gồm: actionscript3, bash, clojure, coldfusion, cpp, csharp, css, delphi, diff, erlang, fsharp, go, groovy, html, java, javafx, javascript, latex, matlab, objc, perl, php, powershell, python, r, ruby, scala, sql, text, vb, xml.

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *