Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Làm chủ AJAX trong Ruby on Rails: Tương tác Web Động, Bất đồng bộ

Hãy hiểu tại sao AJAX tồn tại, để bạn có ý tưởng tốt hơn về cách sử dụng nó trong dự án Rails của mình.

Khi bạn truy cập một trang web, điều gì xảy ra?

Một trang được tải từ server. Nhưng nếu bạn muốn xem thông tin mới, bạn phải tải lại trang để cập nhật, hoặc click link để truy cập trang khác.

Đây là luồng đồng bộ (synchronous).

Dữ liệu mới chỉ được trình bày khi một trang mới được yêu cầu từ server.

Nhưng…

Điều gì xảy ra nếu bạn không muốn tải lại trang?

Điều gì nếu bạn muốn lấy dữ liệu từ backend, bất cứ lúc nào, để cập nhật bất kỳ phần nào của trang hiện tại?

Đây chính là lúc AJAX xuất hiện.

AJAX là viết tắt của Asynchronous Javascript & XML (Javascript và XML bất đồng bộ).

Đó là một kỹ thuật độc lập với framework web của bạn, nhưng Rails cụ thể có hỗ trợ tốt cho nó như bạn sẽ học trong bài này.

Hãy nhớ rằng thêm AJAX vào ứng dụng làm cho nó phức tạp hơn.

Yêu cầu AJAX trực tiếp (Direct AJAX Request)

AJAX có hai phần: yêu cầu (request), bạn thực hiện từ trình duyệt dùng Javascript, và phản hồi (response), bạn xử lý từ ứng dụng Ruby.

Bạn có thể tạo yêu cầu AJAX với Javascript thuần túy.

Nhưng vì điều đó đòi hỏi nhiều boilerplate code, chúng ta thường làm điều này qua thư viện Javascript như jQuery.

Yêu cầu jQuery trông như sau:

$.get(
  "/vegetables",
  function(data) {
    alert("Vegetables are good for you!");
  }
);

Tuy nhiên, kể từ Rails 5.1, jQuery không có sẵn theo mặc định (nhưng bạn có thể thêm lại).

Lưu ý: Bạn sẽ gặp lỗi InvalidAuthenticityToken khi làm yêu cầu POST jQuery, điều này có nghĩa là bạn cần gửi csrf-token từ trang hiện tại như biện pháp bảo mật. Việc dùng Rails.ajax làm điều này tự động.

Có giải pháp!

Rails bao gồm hàm AJAX riêng:

Rails.ajax({
  url: "/books",
  type: "get",
  data: "",
  success: function(data) {},
  error: function(data) {}
})

Nhớ rằng, đây vẫn là phía yêu cầu (request side), từ trình duyệt.

Tức là đây là code Javascript.

Trong Rails, chức năng AJAX này được cung cấp bởi thứ gọi là "Unobtrusive JavaScript", hoặc "UJS" viết tắt.

Cập nhật Partial với AJAX

Nếu bạn muốn chỉ cập nhật một phần trang với dữ liệu từ AJAX, bạn chủ yếu có hai lựa chọn.

  1. Bạn có thể viết một view Javascript + ERB, cập nhật element
  2. Bạn có thể trả về phản hồi JSON từ controller với HTML mới dưới dạng chuỗi, sau đó dùng Javascript để cập nhật element

Còn có một lựa chọn thứ 3.

Nó liên quan đến việc trả về chỉ dữ liệu dưới dạng JSON, sau đó tạo element HTML bằng Javascript dùng dữ liệu đó.

Đây là nơi các framework JS như React xuất hiện.

Theo ý kiến của tôi, chúng thêm nhiều phức tạp không cần thiết.

Nhưng chúng ta có thể xử lý bằng Javascript thuần túy!

Đó là lựa chọn 1 và 2.

Hãy cứ dùng những cái đó cho đến nay 🙂

Ví dụ view Javascript:

Rails.$('.random-number')[0].innerHTML = ("<%= j (render partial: 'random') %>")

j là bí danh cho escape_javascript

Ví dụ jQuery:

$('.random-number').html("<%= j (render partial: 'random') %>")

Cả html và innerHTML đều thay thế nội dung của element mục tiêu.

Bạn cũng có thể append (jQuery) một element mới vào danh sách thay vì thay thế toàn bộ.

Đặt code này trong file có đuôi .js.erb, với tên action hiện tại (như create.js.erb) và bên trong thư mục views.

Ở controller, bạn có thể render view này giống như bất kỳ view nào khác.

Bây giờ:

Khi bạn thực hiện lời gọi AJAX, code Javascript này sẽ chạy tự động và cập nhật HTML.

Hãy xem lựa chọn thứ 2.

Code controller:

render json: { html: render_to_string(partial: 'random') }

Sau đó từ code Javascript của bạn:

Rails.ajax({
  url: "/books",
  type: "get",
  success: function(data) {
    Rails.$(".random-number")[0].innerHTML = data.html;
  }
})

Đó là cách khác để làm điều này!

Bạn nên dùng cái nào?

Cách đầu tiên là yêu thích của DHH, ông gọi nó là "SJR" (Server-Generated Javascript).

Tôi đoán đó là cách Rails muốn bạn làm, nhưng hãy tự thử cả hai (SJR và render_to_string) và xem cái nào phù hợp nhất cho bạn.

Cách dùng HAML cho JS Views

Được.

Giả sử bạn dùng HAML.

Có thể dùng kỹ thuật SJR này và render view .js.haml không?

Có!

Ví dụ:

- content = j (render partial: "random")
Rails.$('.random-number')[0].innerHTML = ("#{content}")

Hơi xấu hơn phiên bản ERB, nhưng nó hoạt động.

Cách Submit Form Rails mà không tải lại trang

Nếu bạn muốn submit form dùng AJAX, bạn có thể làm điều đó mà không cần viết yêu cầu AJAX.

Rails có thể lo việc đó cho bạn.

Làm thế nào?

Dùng tùy chọn remote: true với form_for.

Ví dụ:

<%= form_for @fruit, remote: true do |f| %>
  <%= f.label :name, 'Fruit' %>
  <%= f.text_field :name %>
  <%= f.submit 'Create' %>
<% end %>

Bây giờ khi bạn click "Create", Rails sẽ gửi yêu cầu AJAX cho bạn và trang sẽ không tải lại.

Nếu bạn muốn hiển thị lỗi validation, bạn sẽ phải tạo và render một view Javascript (.js.erb file) thay thế lỗi hiện tại bằng lỗi mới.

Giống như ví dụ ở "Cập nhật Partial với AJAX".

Bên cạnh ra, tùy chọn remote này cũng có thể dùng với link, để bạn có thể làm yêu cầu AJAX delete.

Ví dụ:

<%= link_to "Delete", book_path(book), { method: "delete", remote: true, data: { confirm: "Are you sure?" } }

Bạn có thể xử lý phản hồi bằng view Javascript.

Nếu bạn muốn xử lý cả yêu cầu HTML (từ tải lại trang) và yêu cầu AJAX, bạn sẽ phải dùng شيئا như phương thức respond_to.

Ví dụ:

respond_to do |f|
  f.html { redirect_to :index }
  f.js
end

Trong ví dụ này, có thể dễ dàng hơn để Turbolinks xử lý việc này.

Bạn vẫn có thể làm yêu cầu AJAX và redirect_to từ controller (không cần respond_to), sau đó Turbolinks sẽ thay thế nội dung trang mà không tải lại.

AJAX không hoạt động? Đây là một số mẹo

Nếu yêu cầu AJAX của bạn không hoạt động, bạn có việc debug phải làm.

Đầu tiên, mở công cụ phát triển trình duyệt (developer tools).

Bạn muốn xem panel console để tìm lỗi Javascript.

Sửa chúng.

Cũng hãy chắc chắn rằng bất kỳ CSS selector nào bạn đang target là đúng và bạn không có lỗi chính tả.

Sau đó, kiểm tra rails logs để tìm lỗi.

Sau đó, đảm bảo view đúng đang được render.

Nếu bạn làm theo quy trình này, bạn nên có thể tìm ra tại sao AJAX không hoạt động và sửa nó.

Tóm tắt

Bạn đã học về AJAX, một kỹ thuật phát triển web cho phép bạn tạo Yêu cầu Bất đồng bộ (Asynchronous Request)!

Bạn cũng đã học cách triển khai điều này trong Rails. Hãy nhớ rằng AJAX không bắt buộc để ứng dụng Rails thông thường (không dùng JS framework) hoạt động, nhưng nó là thứ hữu ích để có trong hộp công cụ của bạn.

Đừng quên chia sẻ bài viết này để nhiều người hơn có thể hưởng lợi 🙂

Cảm ơn bạn đã đọc!