Drupalに新しいAjaxされたコンテンツにDrupalの動作を強制する[Drupal.attachBehaviors()のみが正しく機能していない]


10

私はこのトピックについてdrupal.orgに多くの投稿をしていましたが、残念ながら間違ったコンテキストでした。

それは問題ではないと思うので、別の方法で試してみます。おそらくこれが解決策になるかもしれません。PHPページ全体をロードしてajaxで特定のdivを抽出しても、正しく機能しませんでした。だから、私はdrupalにコンテンツだけをロードさせて、それをajaxでdivに注入できると思いました。リクエストされたURLで「ajax = 1」を探しているhook_preprocess_pageとhook_preprocess_nodeを使用してクエリを作成し、ページ全体ではなくコンテンツのみを提供しました。そして今、特定のtpl.phpファイルの助けを借りて、理論的には、drupalの出力を$ contentのみに制限することができました。そしてここに問題があります。tpl.phpファイルを元の方法のままにしても、私のアプローチは機能していますが、node-ajax.tpl.phpから「$ content」を削除しています。「正しく動作する」とは、drupalがページ全体をリロードしないことを意味します。しかしもちろんコンテンツではありません。しかし、私はそれを自分自身に説明することはできません。$ content変数で発生するため、生成されたコンテンツのhtmlのみであると思いました。だから私の質問は、drupalの出力をコンテンツだけに制限するにはどうすればよいですか、またはこれを機能させるために間違った手順を実行していますか?これが私が使用しているモジュールとjsファイルです:my_ajax.module:

<?php

function my_ajax_init()
{
    drupal_add_js(drupal_get_path('module', 'my_ajax') . '/my_ajax.js');
}

function my_ajax_preprocess_page(&$vars, $hook)
{

    if (isset($_GET['ajax']) && $_GET['ajax'] == 1)
    {
        $vars['template_file'] = 'page-ajax';
    }
}

function my_ajax_preprocess_node(&$vars, $hook)
{

    if (isset($_GET['ajax']) && $_GET['ajax'] == 1)
    {
        $vars['template_file'] = 'node-ajax';
    }
}

my_ajax.js:

Drupal.behaviors.my_ajax = function (context) {
    $('#content-group-inner .node a').live('click', function (e) {
        var url = $(this).attr('href');
        //$('#content-region-inner').slideUp('slow');
        $('#content-region-inner').empty().html('<img src="ajax-loader.gif" style="margin-left:50%;"/>');
        xhr = $.ajax({
            data: 'ajax=1',
            type: 'GET',
            url: url,
            success: function (data) {
                $('#content-region-inner').html(data);
                Drupal.attachBehaviors(context);
            }
        });
        return false;
    });
};

これで私を助けてください。すべての提案に感謝します。


2
ほんの小さなコメントD7は、パスで/ nojsと/ ajaxを使用して、ajaxリンクと標準のリンクを区別しています。それは後であなたにいくつかの頭痛を節約するかもしれません。
ジェレミーフランス語、

回答:


11

私はそれを持っている。これは正しく機能しています:

Drupal.behaviors.my_ajax = function (context) {
    $('#content-group-inner a').live('click', function (e) {

        $('#content-group-inner a').addClass('my_ajax-processed');
        var url = $(this).attr('href');
        $('#content-region-inner').empty().html('<img src="ajax-loader.gif" style="margin-left:50%;"/>');        
        $('#content-region-inner').load(url,'ajax=1',function() {
                        Drupal.attachBehaviors('#content-region-inner');
                        });
        return false;
        });
   };

ご協力ありがとうございます。


1
自分の回答を承認済みとしてマークすることを忘れないでください(そして、役に立ったすべての回答に賛成投票してください)。これにより、この質問は概要で解決済みとしてマークされます。さらに賛成投票は、ユーザーが良い答えを提供するように促すのに役立ちます。
Berdir 2011年

また、アタッチする際には「コンテキスト」を使用する必要があります。
Josh Koenig

.live()に注意するだけで非推奨になりました
ErichBSchulz 2013年

使用しないcontext(Josh Koenigが指摘したように)ことは、大きな問題です。イベントハンドラーがページ上のすべての要素に再アタッチされます。を使用する場合context、このコードは変更する必要があります。コンテンツが置き換えられるときの最初のイベントバインディングのcontext包含documentと要素自体であるため、シンプルで$('#content-group-inner a',context)は機能しません。
Alex Skrypnyk 2017

10

あなたの問題は、あなたの成功関数がスコープ内に変数コンテキストを持たないため、アタッチ動作が未定義で機能することだと思います。

あなたができると思います

Drupal.attachBehaviors($('#content-region-inner'));

成功関数はクロージャーであり、変数context(新しいマークアップではなく古いコンテキストです)をスコープ内に保持すると思いました。それは間違っていますか?
アンディ

この場合はクロージャーとして機能する思わないが、私はそれについて非常に間違っている可能性がある。
ジェレミーフランス語、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.