Tworzenie prostej tabeli tak:
kod
CREATE TABLE progress_data (
statusId int(4) NOT NULL AUTO_INCREMENT,
progress float DEFAULT NULL COMMENT 'percentage',
PRIMARY KEY (id_progress_data)
);
JQuery:
//this uses Jquery Timers http://plugins.jquery.com/project/timers
$('#bUpdate').click(function() {
//first obtain a unique ID of this operation - this has to by synchronized
$.ajaxSetup({'async': false});
$.post('ajax.php', {'operation': 'beginOperation'}, function(data) {
statusId = parseInt(data.statusId);
});
//now run the long-running task with the operation ID and other params as necessary
$.ajaxSetup({'async': true});
$.post('ajax.php', {'operation': 'updateSite', 'statusId': statusId, 'param': paramValue}, function(data) {
$('#progress_bar').stopTime('statusLog'); //long operation is finished - stop the timer
if (data.result) {
//operation probably successful
} else {
//operation failed
}
});
//query for progress every 4s, 'statusLog' is just the name of the timer
$('#progress_bar').everyTime('4s', 'statusLog', function() {
var elm = $(this);
$.post('ajax.php', {'operation': 'showLog', 'statusId': statusId}, function(data) {
if (data) {
//set bar percentage
$('#progress').css('width', parseInt(data.progress) + '%');
}
});
});
return false;
}
kod Backend (w PHP):
if (isset($_POST['operation'])) {
ini_set("display_errors", false);
session_write_close(); //otherwise requests would block each other
switch ($_POST['operation']) {
/**
* Initialize progress operation, acquire ID (statusId) of that operation and pass it back to
* JS frontend. The frontend then sends the statusId back to get current state of progress of
* a given operation.
*/
case 'beginOperation': {
$statusId = //insert into progress_data
echo json_encode(array('statusId' => $statusId));
break;
}
/**
* Return back current progress state.
*/
case 'showLog': {
$result->progress = (float) //SELECT progress FROM progress_data WHERE statusId = $_POST['statusId']
echo json_encode($result);
break;
}
case 'updateSite': {
//start long running operation, return whatever you want to, during the operation ocassionally do:
UPDATE progress_data SET progress=... WHERE statusId = $_POST['statusId']
}
}
}
/* Terminate script, since this 'view' has no template, there si nothing to display.
*/
exit;
Użyłem tego podejścia w 3 aplikacje już i muszę powiedzieć, że jest bardzo niezawodny i szybki enogh (operacja showLog jest po prostu prostą instrukcją SELECT). Możliwe jest również użycie sesji do przechowywania postępu, ale to przynosi wiele problemów, ponieważ sesja musi być zapisana jako zamknięta (jeśli jest przechowywana w plikach), w przeciwnym razie zapytania AJAX showLog będą czekać na zakończenie długiej operacji (i luźny sens).
Co to są zabawne instrukcje ładowania, aby użytkownicy byli zadowoleni? http://stackoverflow.com/questions/182112/what-are-some-funny-loading-statements-to-keep-users-amused –
możliwy duplikat [Pokaż postęp podczas długiego połączenia Ajax] (http: // stackoverflow .com/questions/2572830/show-progress-during-a-long-ajax-call) –
@Amr - Ale te nie pokazują postępu, tylko że coś jest ładowane. –