Hướng dẫn dùng ajax 1999 trong PHP

Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)

Nếu đã theo dõi ba bài hướng dẫn trước, thì bạn chắc đã hiểu rõ về AJAX. Trong bài cuối cùng này, chúng ta sẽ tổng hợp mọi thứ bằng cách làm việc với một ví dụ phức tạp hơn.

Mã HTML

Để có được một ý tưởng về cấu trúc của ví dụ này, hãy xem các mã đánh dấu sau đây:

      

Mã đánh dấu cho phần tử main được hiển thị dưới đây:

      

Popular front-end frameworks

Click each one to load details via AJAX.

Lưu ý các liên kết. Những liên kết này tương ứng với các framework khác nhau cho front-end. Như chúng ta sẽ thấy trong phần tiếp theo, mỗi khi chúng ta nhấn vào các liên kết, một yêu cầu AJAX sẽ được thực hiện. Sau đó, phần tử với lớp modal sẽ xuất hiện và nội dung của nó sẽ được cập nhật bằng các dữ liệu lấy được từ dữ liệu trả về.

Dưới đây là minh hoạ cho phần tử main:

Hướng dẫn dùng ajax 1999 trong PHP

Mã đánh dấu của Modal

Bước tiếp theo là xem xét cấu trúc của modal. Dưới đây là mã HTML nó:

      

Như bạn thấy, modal có chứa một vài phần tử rỗng. Chúng ta đặt chúng trong HTML bởi vì văn bản của chúng sẽ thay đổi tùy thuộc vào liên kết mà chúng ta bấm vào và dữ liệu trả về mà chúng ta lấy được.

Hình ảnh dưới đây cho thấy cách modal xuất hiện lần đầu:

Hướng dẫn dùng ajax 1999 trong PHP

Theo mặc định, modal bị ẩn. Ngoài ra, chúng ta cũng sẽ ẩn loader. Nó sẽ chỉ xuất hiện khi yêu cầu AJAX được kích hoạt.

Hãy xem các luật CSS tương ứng:

      .modal {
          opacity: 0; 
      }

      .loader {
          display: none;
      }

Lưu ý rằng chúng ta sử dụng thuộc tính opacity (mà không phải thuộc tính display) để ẩn modal bởi vì thuộc tính này là thuộc tính có thể thực hiện hiệu ứng động của CSS. Bằng cách này, chúng ta sẽ có thể thực hiện hiệu ứng chuyển tiếp các trạng thái của modal (đó là trạng thái mở và đóng).

Tạo ra dữ liệu trả về JSON

Đối với các mục đích của ví dụ này, chúng ta sẽ chọn xây dựng dữ liệu trả về JSON của chính chúng ta. Cụ thể, phản hồi mong muốn (là tập tin Demo.json) sẽ là một mảng của các đối tượng. Mỗi đối tượng sẽ chứa thông tin chi tiết về các framework có liên quan cho front-end.

Hơn nữa, giá trị của thuộc tính name sẽ phù hợp với các liên kết văn bản của phần tử main (xem phần trước). Với ý nghĩ đó, cấu trúc của dữ liệu trả về trông giống như thế này:

       [
         {
           "url": "http://getbootstrap.com/", 
           "numberOfStars": "88.260+", 
           "currentVersion": "3.3.5", 
           "name": "Bootstrap"
         }, 
         {
           "url": "http://foundation.zurb.com/", 
           "numberOfStars": "21.180+", 
           "currentVersion": "5.5.3", 
           "name": "Foundation"
         }, 
         // 4 more objects here
       ]

Lưu ý: các giá trị mà chúng ta sử dụng cho thuộc tính numberOfStarscurrentVersion là giả và hoàn toàn cho mục đích của minh hoạ.

Tương tự như các ví dụ trước đó trong loạt bài này, chúng ta sẽ sử dụng AJAX để yêu cầu một tập tin tĩnh. Tuy nhiên, nếu chúng ta muốn nhúng nội dung từ các trang web khác (ví dụ như Google Maps, Flickr), chúng ta nên đọc tài liệu API của chúng, và nếu cần thiết, áp dụng một API key.

Hơn nữa, dữ liệu mục tiêu của chúng ta đặt trên cùng một máy chủ với trang demo. Do đó, chúng ta sẽ hạn chế các giới hạn đó có thể xảy ra khi tương tác với các dịch vụ bên thứ ba (xem phần "Hạn chế của các yêu cầu AJAX" trong phần sau của bài này).

Cài đặt yêu cầu AJAX

Trong phần này, chúng ta sẽ sử dụng hàm ajax của jQuery để khởi tạo một yêu cầu AJAX. Trước khi làm như vậy, đầu tiên hãy xác định các biến của chúng ta bằng cách lưu bộ nhớ đệm các selector thường dùng nhất của jQuery:

      var $list    = $('.m-info'),
      var $message = $('.m-message');
      var $modal   = $('.modal');
      var $loader  = $('.loader');
      var $framework;

Bây giờ là lúc để xem xét đoạn mã tương ứng cho việc thực thi của yêu cầu:

      $('.boxes a').on('click', function(e) {
        e.preventDefault();
        
        $framework = $(this).text();
        
        $.ajax({
          url: 'Demo.json',
          dataType: 'json',
          beforeSend: function() {
              $loader.show();
          }
        }).done(successFunction)
          .fail(errorFunction)
          .always(alwaysFunction);
      });

Bạn sẽ nhận thấy cú pháp cho hàm ajax trông như sau:

      $.ajax([settings])

Tham số settings là một đối tượng cấu hình nắm giữ các thông tin về yêu cầu của chúng ta. Số lượng các thuộc tính mà đối tượng này có thể có là rất dài (khoảng 34 thuộc tính). Để đơn giản, chúng ta sẽ chỉ thảo luận về những cái được sử dụng trong bản demo này. Cụ thể hơn:

Thuộc tínhMô tả
url Một chuỗi chứa URL mà yêu cầu được gửi tới.
dataType Định dạng của dữ liệu trả về (json, xml, html).
beforeSend Một hàm callback được thực thi trước khi chúng ta gởi yêu cầu. Ở đây, hàm này thực thi mã để hiển thị loader.

Trước khi chúng ta tiếp tục, cần phải lưu ý đến ba điều:

  • Cũng có một cú pháp khác cho hàm ajax$.ajax(url[, settings])
  • Tất cả các thuộc tính cấu hình của tham số settings là không bắt buộc.
  • Phương thức HTTP mặc định là GET.

Các phương thức Promise

Hàm ajax trả về đối tượng XMLHttpRequest hoặc jqXHR của jQuery. Đối tượng này cài đặt giao diện Promise, và do đó nó có chứa tất cả các thuộc tính, phương thức, và hành vi của một Promise.

Trong ví dụ này, chúng ta sử dụng các phương thức Promise sau đây:

  • done
  • fail
  • always

Phương thức done được kích hoạt nếu yêu cầu thành công. Nó nhận một hoặc nhiều đối số, tất cả đều có thể là một hàm duy nhất hoặc một mảng của các hàm. Ví dụ, trong demo của chúng ta, hàm successFunction() được truyền như một đối số.

Hàm callback (ví dụ successFunction()) nhận ba đối số. Đầu tiên, dữ liệu trả về. Thứ hai, một chuỗi phân loại trạng thái của yêu cầu (xem bài trước để biết các giá trị có thể có của nó). Cuối cùng, đối tượng jqXHR.

Phương thức fail được gọi nếu yêu cầu thất bại. Nó nhận một hoặc nhiều đối số, tất cả đều có thể là một hàm duy nhất hoặc một mảng cả các hàm. Vú dụ, trong demo của chúng ta, hàm errorFunction() được truyền như là một đối số.

Hàm callback (ví dụ errorFunction()) nhận ba đối số: đối tượng jqXHR, một chuỗi phân loại trạng thái của yêu cầu, và một chuỗi khác xác định kết quả lỗi. Lỗi này nhận từ phần văn bản của trạng thái HTTP, chẳng hạn như Not Found hoặc Forbidden.

Các phương thức always được thực thi khi yêu cầu kết thúc, bất kể (tức là phương thức done được thực thi) thành công hay thất bại (tức là phương thức fail được thực thi) của nó. Một lần nữa, nó nhận đối số như là một hàm duy nhất hoặc một mảng các hàm. Ví dụ, trong phần demo của chúng ta, hàm alwaysFunction() được truyền vào như là đối số.

Trạng thái của yêu cầu xác định các đối số của hàm. Trong trường hợp một yêu cầu thành công, thì hàm callback (ví dụ alwaysFunction()) nhận các đối số tương tự như hàm callback của phương thức done. Ngược lại, nếu yêu cầu thất bại, nó nhận các đối số tương tự như hàm callback của phương thức fail.

Lưu ý: Thay vì các phương thức Promise done, failalways được sử dụng trong ví dụ này, chúng ta còn có thể sử dụng các hàm callback success, error, và complete. Các hàm được định nghĩa trong các tham số settings.

Hiển thị Dữ liệu

Nếu yêu cầu thành công, chúng ta có thể lấy dữ liệu trả về. Sau đó, chúng ta phân phối nó để gắn vào trong các phần tử rỗng của modal.

Xem đoạn mã cho hàm callback successFunction:

      function successFunction(data) {
        if (data.length > 0) {
          for (var i = 0; i < data.length; i++) {
            if ($framework === data[i].name) {
              $list.show();
              $message.hide();

              $list.find('li:nth-of-type(2)').text($framework);
              $list.find('li:nth-of-type(4)').text(data[i].currentVersion);
              $list.find('li:nth-of-type(6)').text(data[i].numberOfStars);
              $list.find('li:nth-of-type(8)').html('' + data[i].url + '');
              break;
            } else {
              $list.hide();
              $message.show().text('No data received for this framework!');
            }
          }	
        } else {
          $list.hide();
          $message.text('No data received from your respose!');
        }
      }

Mặc dù chúng ta đã cập nhật nội dung của modal của chúng ta, thì nó vẫn bị ẩn. Nó hiển thị và loader biến mất khi yêu cầu thành công. Sau đó, hàm callback alwaysFunction được thực hiện:

      function alwaysFunction() {
          $loader.hide();
          $modal.addClass('active');
      }

Lớp active trông giống như thế này:

      .active {
        opacity: 1;
        z-index: 10;
        transform: scale(1);  
      } 

Dưới đây bạn có thể thấy diện mạo mong muốn của modal nếu chúng ta nhấn vào liên kết có chữ Bootstrap:

Hướng dẫn dùng ajax 1999 trong PHP

Một vài tình huống

Điều quan trọng cần phải hiểu là các đoạn mã được thực thi trong những trường hợp nhất định. Hãy bao quát hai trường hợp phổ biến:

  • Giá trị của thuộc tính name không phù hợp với các liên kết của phần tử main. Ví dụ, giả sử chúng ta xác định một URL nơi mà giá trị của thuộc tính name của các đối tượng có liên quan đến đến framework Foundation là Foundation2 thay vì Foundation. Trong trường hợp này, nếu chúng ta nhấn vào liên có chữ Foundation, modal dưới đây sẽ xuất hiện:
Hướng dẫn dùng ajax 1999 trong PHP
  • Dữ liệu trả về là rỗng. Ví dụ, chúng ta định nghĩa một URL trỏ đến một mảng rỗng. Trong trường hợp này, modal sẽ trông như thế này:
Hướng dẫn dùng ajax 1999 trong PHP

Xử lý các lỗi

Vì vậy, chúng ta xem xét đoạn mã được chạy khi yêu cầu thành công. Nhưng điều gì sẽ xảy ra nếu yêu cầu thất bại? Trong trường hợp của chúng ta, một yêu cầu không thành công, chúng ta ẩn danh sách và hiển thị một tin nhắn tùy biến.

Đây là đoạn mã của hàm failFunction() minh hoạ hành vi đó:

       function failFunction(request, textStatus, errorThrown) {
         $list.hide();
         $message.text('An error occurred during your request: ' + request.status + ' ' + textStatus + ' ' + errorThrown);
      }

Để tự làm quen với đoạn mã này, chúng ta chỉ định một URL không tồn tại. Do đó, phương thức fail sẽ được kích hoạt và modal bên dưới sẽ được hiển thị:

Hướng dẫn dùng ajax 1999 trong PHP

Lưu ý: Một lần nữa, thông báo lỗi có thể khác nhau nếu bạn chạy ví dụ này tại cục bộ.

Đây là bản demo nhúng từ Codepen:

Kết luận

Trong hướng dẫn này, chúng ta tổng hợp bài nghiên cứu về AJAX từ góc nhìn của một nhà thiết kế - mà bạn đã theo dõi! Tôi hy vọng rằng bạn thấy loạt bài này hữu ích và bạn đã học được một số kỹ năng mới.

Bước tiếp theo, tôi khuyên bạn bạn xem xét những điều sau đây:

  • Làm quen với các phương thức rút gọn của AJAX trong jQuery mà chúng ta chưa tìm hiểu (ví dụ phương thức $.getSON).
  • Cài đặt các yêu cầu AJAX của bạn bằng cách truy xuất các tập tin tĩnh hoặc dữ liệu động đến từ các dịch vụ bên thứ ba (ví dụ Flickr).