WordPressとAjaxに問題があります。
これは私のJavaScriptの部分です(少しトリミングしました):
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) );
});
私のPHPコードは次のとおりです。
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' );
スクリプトは、admin-ajaxからAjax応答を取得します。残念ながら、JavaScriptコードのeach
ステートメントに到達すると、コンソールはエラーをスローします...
"Uncaught TypeError: Cannot use 'in' operator to search for '4' in Array".
「posts」変数のconsole.logを実行すると、文字列「Array」が取得されます。 PHPで$list
変数をどのように渡しても、常に文字列を返します。クエリは他の場所に投稿を返すため、空ではありません。 json_encode
なしで、ヘッダーを宣言して、なしで、wp_send_json()
を使用して、配列をエコーする前にob_clean()
を入れ、配列を配列に入れてみました...しかし、常にajax
は文字列としてArray
およびeach
は循環できません。
これは非常に単純なことで、なぜ機能しないのか理解できません。他のJavaScriptやPHPエラーや警告はありませんが、他のすべては正常に動作します。
BODA82の答え は助けになりました、しかし結局私は私のJavaScriptコードでresponseText
をresponseJSON
メソッドに置き換えるべきであることに気づきました。以下の例では、Ajaxレスポンスの結果を変数に格納していました。 JSONで応答を取得するための特定の方法があることを知りませんでした。このようにして、get_posts()
の結果を持つオブジェクト/配列は、文字列としてではなく正しく返されます。
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
あなた自身に注意してください、そしてまた一般的なアドバイス:あなたが夕方に何かを直すことができないならそれはあなたが寝て本を読んで星を数えるべきサインです。答えは翌朝見つけられるでしょう、早ければ早いほど:D
解決策があります。 complete
またはsuccess
の代わりにdone
を使用します。
posts = $.ajax({
type: 'GET',
url: ajaxurl,
async: false,
dataType: 'json',
data: { action : 'getHotelsList' },
complete: function(results) {
それでも問題が解決しない場合はasync:false
を削除してみてください。
PHP関数とほぼ同じです。ヘッダーを設定する必要はありません。 (編集:また、get_posts()
が実際に結果を返していると仮定します。)
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' );
そしてあなたの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.');
}
});