Поэтому я создаю сайт PHP, такой как Flickr, за исключением того, что эти фотографии можно оценивать. Поэтому я настраиваю систему рейтинга в AJAX, чтобы, когда пользователь нажимает на звезду, чтобы оценить фотографию, звезды на фотографии отражают новый рейтинг, рассчитанный. (рейтинг фото изображен 10 звездами, которые либо желтые, либо пустые).
Звезды реагируют, как они должны, когда вы наводите на них курсор, они загораются до того места, где указывает ваш курсор. Когда вы нажимаете звезду, соответствующее значение регистрируется в таблице photo_rating и обновляется в таблице фотографий. Затем вновь вычисленный рейтинг отражается через звезды.
ОБНОВЛЕНИЕ Это почти все сводится к тому, что этот звонок не возвращает правильный рейтинг, он все равно возвращает исходный рейтинг фотографии при загрузке страницы. И не новый рейтинг, который был сохранен в БД через AJAX (даже если значение в БД было изменено)
onmouseout="stars_current_rating(<?php echo Photograph::find_by_id($_GET['id'])->rating;?>);"
ЗДЕСЬ возникает проблема: после нажатия звездочки обновляется с помощью правильного недавно вычисленного рейтинга. Но когда я снова вернусь к звездам, вытащи. Рейтинг звезд возвращается к первоначальному рейтингу, на котором они были, когда пользователь впервые загрузил страницу. Таким образом, рейтинг, который отражается, является тем, что было вытащено из db при загрузке страницы. Не значение, которое теперь находится в столбце оценок таблицы фотографий.
Первоначально я использовал рейтинг $ photo->, но я понял, что, поскольку я использовал AJAX, значение не возвращалось снова. Итак, я переключил onmouseout на вызов Photograph :: find_by_id ($ _ GET ['id']) -> рейтинг; который должен создавать экземпляр нового объекта, проверяя базу данных с ее идентификатора и получая текущий рейтинг. Но даже это, похоже, не дает мне обновленную ценность.
Я использовал firebug, firePHP и делаю профилирование, чтобы точно видеть, какие значения передаются в эти методы, когда я нажимаю и нажимаю на них. По какой-то причине новый рейтинг вытягивается из БД сразу после того, как пользователь проголосовал за новое значение. Но в любое время после того, как вы наведите указатель мыши на звезды, они вернутся к тому, что было, когда вы загрузили страницу. В любом случае, я могу получить это обновленное значение, которое будет отражено в коде ниже, без обновления всей страницы? Если я обновляю страницу, тогда она работает, но все дело в том, чтобы все это сделать через AJAX, поэтому всю страницу не нужно перезагружать …
Вот как настроены вызовы на странице.
<div id="rating" class="rating"> <?php for($i=1; $i<11; $i++){ ?> <a id="rating_star<?php echo $i ?>" href="#" onmouseover="decide_rating(<?php echo $i ?>);" onmouseout="stars_current_rating(<?php echo Photograph::find_by_id($_GET['id'])->rating;?>);" onmousedown="set_rating(<?php echo $photo->id.", ".$i ?>);"> <img id="star<?php echo $i ?>" class="rating_star" src= <?php // keeps stars always set at rating for photo when not being rated if($photo->rating >= $i){ echo "images/assets/rating_star.png"; } else { echo "images/assets/rating_star_off.png"; } ?> /> </a> <?php } ?> </div>
Вот мой файл ratings.js, который содержит 3, используемые выше для onmouseactions (я понимаю, что decision_rating и stars_current_rating – это тот же код, они были разными, когда я настраивал их для другой страницы, где логика была другой, но обновление не работал, поэтому я вернулся к этому более простому примеру)
// Makes stars light up, up to where you have your cursor pointing // pass in current rating of star hovered over function decide_rating( r ){ for(var i=1; i<=10; i++){ var star = document.getElementById("star"+i); if(i<=r){ star.src = "images/assets/rating_star.png"; } else { star.src = "images/assets/rating_star_off.png"; } } return false; } // defaults the stars to light up with the current rating function stars_current_rating(r){ for(var i=1; i<=10; i++){ var star = document.getElementById("star"+i); if(i<=r){ star.src = "images/assets/rating_star.png"; } else { star.src = "images/assets/rating_star_off.png"; } } return false; } function set_rating(pid, rating){ if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function(){ if(xmlhttp.readyState==4 && xmlhttp.status==200){ // no message to be displayed //document.getElementById("message").innerHTML=xmlhttp.responseText; // for this to work ratings.js must be before this file when linked to // set_ratings is echoing the $photo->rating for the calling pid // as the xmlhttp.responseText stars_current_rating(xmlhttp.responseText); } } xmlhttp.open("GET","../includes/set_rating.php?pid="+pid+"&rating="+rating,true); xmlhttp.send(); }
в// Makes stars light up, up to where you have your cursor pointing // pass in current rating of star hovered over function decide_rating( r ){ for(var i=1; i<=10; i++){ var star = document.getElementById("star"+i); if(i<=r){ star.src = "images/assets/rating_star.png"; } else { star.src = "images/assets/rating_star_off.png"; } } return false; } // defaults the stars to light up with the current rating function stars_current_rating(r){ for(var i=1; i<=10; i++){ var star = document.getElementById("star"+i); if(i<=r){ star.src = "images/assets/rating_star.png"; } else { star.src = "images/assets/rating_star_off.png"; } } return false; } function set_rating(pid, rating){ if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function(){ if(xmlhttp.readyState==4 && xmlhttp.status==200){ // no message to be displayed //document.getElementById("message").innerHTML=xmlhttp.responseText; // for this to work ratings.js must be before this file when linked to // set_ratings is echoing the $photo->rating for the calling pid // as the xmlhttp.responseText stars_current_rating(xmlhttp.responseText); } } xmlhttp.open("GET","../includes/set_rating.php?pid="+pid+"&rating="+rating,true); xmlhttp.send(); }
У меня это установлено с 2 таблицами в моей базе данных. Один – photo_rating, который имеет user_id, photo_id и рейтинг. В таблице фотографий также есть столбец для текущего рейтинга (который вычисляется как среднее значение соответствующих строк в photo_rating).
Ниже представлен файл set_rating.php, который AJAX вызывает
<?php // This file is called by the ratings.js function set_rating // echo output is used by to update the current rating of the // photo after it has been saved in the database require_once('initialize.php'); // create new photo rating and set up attributes if(isset($session->user_id)){ $pr = new PhotoRating( $_GET['pid'], $session->user_id, $_GET['rating']); } else { $pr = new PhotoRating( $_GET['pid'], NULL, $_GET['rating']); } // save the rating in photo_ratings table // and the rating in the photograph table $pr->save_rating_update_photo(); echo Photograph::find_by_id($_GET['pid'])->rating; ?>
И это функции, которые вызывают в PhotoRating
// saves the current photo_rating into the database // Then calls update photo rating up update the // rating in the photo database table function save_rating_update_photo(){ if($this->save()){ // Success $message = "entry saved in photo_rating"; //$session->message("{$photo->filename} was uploaded"); } else { // Failure $message = join("<br />", $this->errors); } $this->update_photo_rating(); } function update_photo_rating(){ $photo = Photograph::find_by_id($this->p_id); $newRating = ($this->rating + self::sum_all_ratings($this->p_id))/($this->count_all()+1); $photo->rating = $newRating%10; if($photo->save()){ // Success } else { // Failure $message = join("<br />", $photo->errors); } }
Любое понимание было бы оценено, я стучал головой о стол, так как я начал тестировать это вчера. Я понимаю, что могу просто перезагрузить страницу, но я чувствую, что это отрицает эффективность того, что все это происходит через AJAX.