Nếu bạn chưa biết AJAX là gì thì có thể hiểu đơn giản đây là một công nghệ của Javascript, hỗ trợ chúng ta trao đổi dữ liệu giữa server và client (trình duyệt) mà không cần phải gửi các lệnh HTTP thông thường, tức là không cần phải load lại trang web.
Chúng ta sẽ áp dụng AJAX vào nút ‘Add to cart’ để thêm sản phẩm vào giỏ hàng mà không cần phải load lại trang.
Ở phía client, chúng ta sửa lại file index.html.erb
trong thư mục app/views/store
như sau:
<% if notice %> <p id="notice"><%= notice %></p> <% end %> <h1>Product List</h1> <% @products.each do |product| %> <div class="entry"> <%= image_tag(product.image_url) %> <h3><%= product.title %></h3> <%= sanitize(product.description) %> <div class="price_line"> <span class="price"><%= number_to_currency(product.price) %></span> <%= button_to 'Add to Cart', line_items_path(:product_id => product), :remote => true %> </div> </div> <% end %>
Ở hàm button_to,
chúng ta thêm thuộc tính :remote
là true,
và khi bấm vào nút thì trình duyệt sẽ gởi một lời gọi AJAX, thay vì một lời gọi HTTP như bình thường.
Nút này vẫn sẽ gửi tới hàm create
trong lớp LineItemsController,
do đó ở phía server chúng ta sửa lại như sau:
class LineItemsController < ApplicationController . . . # POST /line_items # POST /line_items.json def create @cart = current_cart product = Product.find(params[:product_id]) @line_item = @cart.add_product(product.id) respond_to do |format| if @line_item.save format.html { redirect_to('/', :notice => 'Line item was successfully created') } format.js format.json { render :show, status: :created, location: @line_item } else format.html { render :new } format.json { render json: @line_item.errors, status: :unprocessable_entity } end end end . . . end
Dòng format.js
sẽ làm công việc trả lời cho các lời gọi AJAX, mặc định dữ liệu trả về sẽ được gửi trong một file Javascript có tên <tên_phương_thức_routing>.js.erb
trong thư mục app/views/<tên_controller>,
tức là ở đây sẽ trả về file create.js.erb
trong thư mục app/views/line_items.
Do đó chúng ta tạo file create.js.erb
có nội dung như sau:
var content = "<%= escape_javascript(render(current_cart)) %>"; document.getElementById("cart").innerHTML = content;
Nếu bạn đã từng làm việc với Javascript thì đoạn code trên cũng không có gì khó hiểu, chỉ khác là chúng ta có thể gọi thêm cả code ERB của Rails trong này. Ở đây chúng ta thay thế nội dung trong thẻ có id
là cart
với biến đã được khai báo là content
. Biến này chúng ta truyền vào giá trị lấy từ hàm render current_cart
.
Vậy là xong, bây giờ nút ‘Add to cart’ sẽ gửi các lời gọi AJAX thay cho lời gọi HTTP bình thường. Bạn có thể kiểm tra bằng cách để ý icon trên tab của trình duyệt không hiển thị thành vòng tròn xoay, hoặc rõ hơn là lời nhắn thêm sản phẩm thành công của biến :notice
là 'Line item was successfully created'
không hiện ra khi chúng ta thêm sản phẩm mới.
Không có AJAX:
Có AJAX: