Mam problem z WordPressem i Ajax.
To jest moja część JavaScript (trochę ją przyciąłem):
var posts = $.ajax({ type: "POST", url: ajaxurl, async: false, dataType: "json", data: { action: "myAjaxFunc" }, done: function(response) { return response; } }).responseText; $.each(posts, function() { $("#someSelect").append( $("<option</option>").text(this.name).val(this.id) ); });
Mój kod PHP wygląda następująco:
function myAjaxFunc() { $posts = get_posts( array( "posts_per_page" => -1, "orderby" => "title", "order" => "ASC", "post_type" => "my-post-type", "post_status" => array( "publish", "draft" ) ) ); $list = array(); foreach ( $posts as $post ) { $list[] = array( "id" => $post->ID, "name" => $post->post_title, "link" => get_permalink( $post->ID ), ); } header("Content-type: application/json"); echo json_encode( $list ); die; } add_action( "wp_ajax_nopriv_myAjaxFunc", "myAjaxFunc" ); add_action( "wp_ajax_myAjaxFunc", "myAjaxFunc" );
Skrypt pobiera odpowiedź Ajax od admin-ajax. Niestety konsola wyświetla błąd, gdy dotrze do instrukcji each
w kodzie JavaScript … wyświetla komunikat:
"Uncaught TypeError: Cannot use "in" operator to search for "4" in Array".
Jeśli zrobię console.log moich „postów” var, otrzymam ciąg „Array”. Bez względu na to, jak przekażę zmienną $list
w PHP, zawsze zwróci ciąg. Zapytanie zwraca posty w innym miejscu, więc nie jest puste. Próbowałem bez json_encode
, z zadeklarowanym nagłówkiem i bez, używając wp_send_json()
, wstawiając ob_clean()
przed wyświetleniem echa tablicy, umieszczeniem tablicy w tablicy … Ale zawsze trafia do ajax
jako ciąg znaków Array
i each
nie mogą przez to przechodzić.
To powinno być bardzo proste i nie mogę zrozumieć, dlaczego tak jest nie działa. Nie mam innych błędów ani ostrzeżeń JavaScript ani PHP, a wszystko inne działa poprawnie.
Komentarze
- Co widzisz, gdy przejdź do example.com/wp-admin/admin-ajax.php?action=myAjaxFunc
- Czy są jakieś postępy w Twoim pytaniu? Czy mógłbyś kontynuować?
- och … to jest sprzed 5 miesięcy … Odpowiedziałem na swoje pytanie tak, jak następnego dnia je opublikowałem, używając fragmentów odpowiedzi BODA82 – ja po prostu nie ' t oznaczył to jako poprawną odpowiedź; @toscho dodał swoje dalsze uwagi znacznie później, wczoraj, mogę ' sprawdzić, czy jego odpowiedź jest teraz również dobra, chociaż ma to sens
Odpowiedź
Odpowiedź BODA82 pomogła , ale w końcu zdałem sobie sprawę, że powinienem był zastąpić responseText
z metodą responseJSON
w moim kodzie JavaScript. W poniższym przykładzie zapisałem wyniki odpowiedzi Ajax w zmiennej. Nie wiedziałem istniała specjalna metoda uzyskiwania odpowiedzi w formacie JSON. W ten sposób obiekt / tablica z wynikami get_posts()
jest zwracany poprawnie, a nie jako ciąg:
posts = $.ajax({ type: "GET", url: ajaxurl, async: false, dataType: "json", data: { action : "getHotelsList" }, done: function(results) { // Uhm, maybe I don"t even need this? JSON.parse(results); return results; }, fail: function( jqXHR, textStatus, errorThrown ) { console.log( "Could not get posts, server response: " + textStatus + ": " + errorThrown ); } }).responseJSON; // <-- this instead of .responseText
Uwaga dla siebie, ale też ogólna rada: jeśli nie możesz czegoś naprawić wieczorem, to znak, że powinieneś iść spać, poczytać książkę i policzyć gwiazdki. Odpowiedź zostanie znaleziona następnego ranka, im wcześniej, tym lepiej: D
Odpowiedź
Prawie gotowe, dzięki funkcji PHP. Nie ma potrzeby ustawiania nagłówka. (Edycja: również zakładając, że get_posts()
w rzeczywistości zwraca wyniki.)
function myAjaxFunc() { $posts = get_posts( array( "posts_per_page" => -1, "orderby" => "title", "order" => "ASC", "post_type" => "my-post-type", "post_status" => array( "publish", "draft" ) ) ); $list = array(); foreach ( $posts as $post ) { $list[] = array( "id" => $post->ID, "name" => $post->post_title, "link" => get_permalink( $post->ID ), ); } echo json_encode( $list ); die; } add_action( "wp_ajax_nopriv_myAjaxFunc", "myAjaxFunc" ); add_action( "wp_ajax_myAjaxFunc", "myAjaxFunc" );
I Twój JavaScript:
$.ajax({ url: "<?php bloginfo("url"); ?>/wp-admin/admin-ajax.php", type: "POST", data: "action=myAjaxFunc", success: function(results) { var posts = JSON.parse(results); console.log(results); $.each(posts, function() { $("#someSelect").append( $("<option></option>").text(this.name).val(this.id) ); }); }, error: function() { console.log("Cannot retrieve data."); } });
Komentarze
- Gdy zapisujesz niektóre dane za pomocą JSON.stringify (), a następnie musisz przeczytać to w php. Poniższy kod zadziałał dla mnie. json_decode (html_entity_decode (stripslashes ($ jsonString)));
Odpowiedź
Jest wyjście. Użyj complete
zamiast success
lub done
:
posts = $.ajax({ type: "GET", url: ajaxurl, async: false, dataType: "json", data: { action : "getHotelsList" }, complete: function(results) {
I spróbuj usunąć async:false
, jeśli problem będzie się powtarzał.