Bài 10: Xử lý tiến trình khi làm việc với ajax

DOWNLOAD DEMO

Có bao giờ bạn gặp sự cố khi viết một chương trình ajax nào đó mà người dùng click liên tục và hệ thống sẽ gửi ajax liên tục? nếu có thì trong bài này tôi sẽ hướng dẫn bạn một cách có thể khắc phục tình trạng này. Tôi sẽ tạm gọi nó là quản lý tiến trình khi gửi ajax. Và trước khi vào nội dung chính như thường lệ tôi sẽ đề cập đến một vài kiến thức mà tôi có sử dụng trong bản demo gửi ajax này.

Hình ảnh ajax đang  loadding

Hình ảnh sau khi load ajax xong

Trước tiên bạn xem hai hình sau đây để dễ hình dung về chức năng mà trong bài chúng ta sẽ xây dựng.

1. Tính toàn cục trong javascript

Tại sao tôi lại gọi là tính toàn cục? tại vì trong javascript nếu bạn bật một tab browser và gõ một đường link vào và chạy lên thì trình duyệt sẽ duyệt qua từng dòng đi từ trên xuống dưới, từ trái qua phải của những đoạn thẻ HTML, nếu gặp JS thì nó sẽ xử lý js và lưu vào bộ nhớ của trình duyệt. Một khi nó lưu rồi thì bạn sẽ hoàn toàn có thể sử dụng nó bất cứ ở đâu, dù trong hàm hay ngoài hàm. Đây chính là một trong những tính chất mà JS không được xếp vào một ngôn ngữ lập trình hướng đối tượng.

2. Hàm always trong jquery ajax

Trong jQuery Ajax sẽ có một trong hai trạng thái là thành công hoặc thất bại và nó cũng có hỗ trợ cho chúng ta hai hàm cấu hình để can thiệp vào đó là success error. Nhưng đôi lúc ta muốn một đoạn mã nào đó dù thành công hay thất bại đều được chạy thì ta phải lặp lại đó code đó ở cả hàm successerror.

Như vậy sẽ không hay lắm, chính vì điều này query có cung cấp cho chúng ta một hàm với tên là always, hàm này dù kết quả trả về của ajax thế nào đi chăng nữa thì nó vẫn gọi tới và xử lý.

Không chần chừ nữa, ta bắt đầu vào tìm hiểu cách quản lý tiến trình khi xử lý ajax nhé.

3. Tạo trang trả về kết quả chuỗi json để ajax gọi tới

Bạn tạo file data.php với nội dung như sau:

$json = '
[
    {
        "username":"thehalfheart",
        "email":"thehalfheart@gmail.com"
    },
    {
        "username":"nvcuongsp",
        "email":"thehalfheart@gmail.com"
    },
    {
        "username":"mrcuongwinter",
        "email":"thehalfheart@gmail.com"
    },
    {
        "username":"ftuts",
        "email":"thehalfheart@gmail.com"
    },
    {
        "username":"freetutorials",
        "email":"thehalfheart@gmail.com"
    }
]';

// Ngủ 5 giây để test ajax
sleep(5);

// Xuất json
echo $json;

Trong file này tôi có khai báo một biến $json, và tôi có dùng hàm sleep để cho server xử lý chậm hơn 5 giây, mục đích là để bên ajax gọi tới nó sẽ ngưng xử lý trong 5 giây để ta có thể kiểm tra được tiến trình. Và cuối cùng tôi echo $json để Ajax có thể nhân chuỗi JSON đó.

4. Tạo file xử lý tiến trình ajax

Bạn tạo file index.html với nội dung như sau:

<!DOCTYPE html>
<html>
    <head>
        <title>Quản lý tiến trình khi gửi ajax</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script language="javascript" src="http://code.jquery.com/jquery-2.0.0.min.js"></script>
    </head>
    
    <body>
        <div id="content"></div>
        <div id="loadding" style="display: none; color:red;">Loadding ...</div>
        <button id="clickmetoload" >Load Content</button>
    </body>
</html>

Trong đoạn mã HTML tôi có tạo một cái div <div id="content"></div>  dùng để hiển thị dữ liệu trả về. Bên dưới div#content tôi có một div hiển thị dòng chữ loadding và một button dùng để click gửi ajax. Mục đích của chương trình này là khi click vào button thì sẽ gửi ajax lấy data, đồng thời sẽ hiển thị chữ loadding... . Nếu như trong quá trình đang gửi mà ta click tiếp thì sẽ thông báo là đang gửi. 

Để làm được thì ta sẽ code js xử lý như sau, bạn sửa lại file index.html với nội dung:

<!DOCTYPE html>
<html>
    <head>
        <title>Quản lý tiến trình khi gửi ajax</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script language="javascript" src="http://code.jquery.com/jquery-2.0.0.min.js"></script>
    </head>
    
    <body>
        <div id="content"></div>
        <div id="loadding" style="display: none; color:red;">Loadding ...</div>
        <button id="clickmetoload" >Load Content</button>
        <script language="javascript">
            
            // Biến kiểm tra
            var ajax_sendding = false;
                
            $('#clickmetoload').click(function()
            {   
                // Xóa nội dung trong thẻ div content
                // dùng cho trường hợp click lần thứ 2 trở đi
                $('#content').html('');
                
                // kiểm tra trạng thái có đang gửi ajax không
                // Nếu đang gửi thì dừng
                if (ajax_sendding == true){
                    alert('Dang Load Ajax');
                    return false;
                }
                
                // Ngược lại thì bắt đầu gửi ajax
                // Nhưng trước hết gán biến ajax_sendding = true để khi người dùng click tiếp 
                // se không có tác dụng
                ajax_sendding = true;
                
                // Bật span loaddding lên
                $('#loadding').show();
                
                // Gửi ajax
                $.ajax({
                    url : 'data.php',
                    type : 'post',
                    dataType : 'json',
                    success : function (result)
                    {
                        // Tạo HTML
                        var html = '<table border="1" cellspacing="0" cellpadding="1">';
                        // Vì kết quả trả về dạng JSON nên ta lặp để lấy kết quả
                        $.each(result, function (key, item){
                            html += '<tr>';
                            html += '<td>'+item['username']+'</td>';
                            html += '<td>'+item['email']+'</td>';
                            html += '</tr>';
                        });
                        html += '</table>';
                        
                        // Gán nội dung html vào thẻ content
                        $('#content').html(html);
                    }
                }).always(function(){
                    ajax_sendding = false;
                    $('#loadding').hide();
                });
                
                // Hàm always có ý nghĩa rằng dù ajax có thành công hay không thì đều chạy hàm này, 
                // mà trong bài này ta muốn sau khi ajax thực hiện xong thì cho phép click load lại được
                // và chữ loadding sẽ biến mất nên ta sẽ dùng nó để thực hiện
            });
        </script>
    </body>
</html>

Trong phần comment tôi đã giải thích đoạn Ajax xử lý rồi, bạn chỉ  lưu ý thêm ở hàm always tôi có sử dụng biến cục bộ ajax_loadding để kiểm soát tiến trình.

Bây giờ chạy chương trình và cảm nhận nhé.

5. Lời kết

Bài này cũng không phải phức tạp gì nhưng thiết nghĩ nếu bạn mới học Ajax thì nó khá quan trọng bởi vì nếu bạn không quản lý tiến trình thì người dùng sẽ click liên tục và ajax sẽ phải gửi liên tục.

Tuy nhiên vẫn còn cách khác là khi click gửi ajax thì ta ẩn luôn button đó hoặc chuyển sang trạng thái disabled để người dùng không thể click tiếp được.

Nguồn: freetuts.net