web-dev-qa-db-ja.com

AjaxコールバックでdrupalSettingsを生成する

Ajax応答で#ajax機能を持つフォームを返します。フォームはページに適切に読み込まれますが、drupalSettingsが返されないため、#ajaxifiedにはなりません。 D7では、次のコードを使用してJS設定AKA Drupal.settingsを生成できます。

$scripts = drupal_add_js();
if (!empty($scripts['settings']))
{
    $settings = '<script type="text/javascript">jQuery.extend(Drupal.settings, ';
    $settings .= drupal_json_encode(call_user_func_array('array_merge_recursive', $scripts['settings']['data']));
    $settings .= ');</script>';
}

私はこのコードに相当するD8を見つけようとしていますが、あまり成功していません。現時点では、ajaxコールバックからJsonResponseを返していますが、おそらくAjaxResponseを返す必要があると考えています。フォームのHTMLとともに設定を返すために、生成されたフォームをAjaxResponseに渡す方法がわかりません。

3
Jaypan

さて、私は自分の質問に答えています。その秘密は、BubbleableMetadataを使用することです。これが私がしたこととそれがどのように起こったかを説明する私のコードです。これが、応答のJSONを生成するコントローラー全体の応答です。

 public function ajax_callback($type)
 {
    // Retrieve the form
    $form = \Drupal::service('form_builder')->getForm('Drupal\path\to\Form');

    // Render the form
    $rendered_form = render($form);

    // Get the data from BubbleMetaData
    $data = BubbleableMetadata::createFromRenderArray($form);
    // Retrieve the attachments from the $data
    $attachments = $data->getAttachments();

    // Generate the settings to be sent back with the ajax response
    if(!empty($attachments['drupalSettings']))
    {
        $settings .= '<script type="text/javascript">jQuery.extend(drupalSettings, ';
        $settings .= Json::encode($attachments['drupalSettings']);
        $settings .= ');</script>';
    }

    // Send back the rendered form along with the settings
    $response = [
        'content' => $rendered_form . $settings,
        'status' => TRUE,
        'type' => $type,
    ];

    // Return the data as a JsonResponse
    return new JsonResponse($response);
}
3
Jaypan

Ajaxコールバックで返す配列のセクションに設定をアタッチできます。

$form['section']['#attached']['drupalSettings']['mysettings'] = ...
return $form['section'];

Replaceなどのhtml挿入コマンドまたはダイアログコマンドを使用する場合は、このコマンドで使用するコンテンツに対して同じことを実行できます。

ajax.jsは、ajax応答を受け取った後、drupal動作と設定を再アタッチします。

1
4k4