2

ajax が正常に実行された後、ajax リンクの URL パラメータを変更するにはどうすればよいですか? 次のコードは機能しませんが、私がやりたいことを説明しています。

CHtml::ajaxLink($text, array('/core/bookmark/create'), array(
    'data' => array("id" => $id),
    'type' => 'GET',
    'success'=>'js:function(data){
        if (data.status == "success"){ 
            //attempt to dynamically change the URL
            this.url = "/core/bookmark/delete";
            $("#bookmark-btn").toggleClass("bookmark_on").toggleClass("bookmark_off");
        }
    }',
), array('id'=>'bookmark-btn', 'class' => 'bookmark_off'));  

の行this.urlは ajaxLink の URL には影響しませんが、コンソールにもエラーは発生しません。

4

3 に答える 3

2

CHtml::ajaxLink属性aを持たない要素をレンダリングします。urlそのようなコードが必要です:

if (data.status == "success"){ 
    jQuery(this).attr('href', '/core/bookmark/delete');
}

アップデート:

その上、私がやりたいのは、リンク自体ではなく、リンクがクリックされたときに起動する Ajax 関数の URL を変更することです。

その場合、より良い解決策は、2 つの要素を描画CHtml::ajaxLinkし、ajax-requests の結果に従ってそれらの可視性を切り替えることです。それはあなたの労力を少なくします。

于 2012-11-12T14:47:51.237 に答える
1

あなたの方法がうまくいかない理由

これが機能しない実際の理由は、将来のオブジェクトの url ではなく、現在のjquery ajax オブジェクトの url プロパティを変更しているためです。これは、生成された html/js を見ると明らかです。

リンク:

<a href="#" class="bookmark_off" id="bookmark-btn">value-of-text</a>

イベント リスナー (以下は通常、最後の<script>before</body>にあります。いくつかのコメントも追加しました):

$('body').on('click','#bookmark-btn',function(){
    jQuery.ajax({'data':{'id':1},'type':'GET',
        'success':js:function(data){
            if (data.status == "success"){
                //attempt to dynamically change the URL
                this.url = "/core/bookmark/delete";
                $("#bookmark-btn").toggleClass("bookmark_on").toggleClass("bookmark_off");
            }
        },
        'url':'/project-name/index.php/core/bookmark/create', // this url is used repeatedly
        'cache':false
    }); // ajax call ends
    return false; // click handler ends
});

上記のリスナーは、クリックごとに新しいajax オブジェクト/呼び出しが作成/実行されることを示しています。したがって、そのオブジェクトの URL のみが変更されるたびに変更されますが、次の呼び出しのために作成される次のオブジェクトは変更されません。次の呼び出しでは、同じ古い URL、つまり : が使用されます'url':'/project-name/index.php/core/bookmark/create',


解決

「ajax リンクの URL を動的に変更する」方法があります。を使用する代わりにCHtml::ajaxLink通常の を使用しますが、CHtml::linkclientChangeオプションを追加します。clientChangeオプションは の 3 番目のパラメータ内、つまり 内に含まれCHtml::linkますhtmlOptionshrefこのようにして、静的 URL の代わりに、ajax 呼び出し用に生成された<a>タグの を使用する ajax 呼び出し用の動的 URL を指定できます。

例(コード内のコメントを読んでください):

echo CHtml::link($text, array('/core/bookmark/create'), array(
    // the htmlOptions array, with clientOptions included
    'id'=>'bookmark-btn',
    'class' => 'bookmark_off',
    'return' => false, // this is already false by default - read documentation
    'ajax' => array( // now specify the ajax options, with a dynamic url
        'url' => 'js:$(this).attr("href")', // this takes the href property of
                // the <a> tag that is generated for this CHtml::link
        'data' => array('id' => $id),
        'custom_data_passed_to_ajax_object' => 'js:this', // this is important,
                // here we pass link, <a> tag, for use within the ajax object
        'success'=>'function(data){
            if (data.status == "success"){ 
                // now change the href of the <a> we passed in custom_data_passed_to_ajax_object
                $(this.custom_data_passed_to_ajax_object).attr("href",
                    "'.$this->createUrl('/core/bookmark/delete').'");
                $("#bookmark-btn").toggleClass("bookmark_on").toggleClass("bookmark_off");
            }
        }'
    )
));

上記のソリューションを実際に次のように適応させることもできますajaxLink

echo CHtml::ajaxLink($text,
    'js:$(this).attr("href")', // this will be generated as 'url':$(this).attr("href")
    array(// ajax options, remember to pass the reference to the <a>,
        // i.e custom_data_passed_to_ajax_object in the above snippet
    ),
    array(
        'href'=>$this->createUrl('/core/bookmark/create'), // your actual url
        // rest of htmlOptions
    )
);

「クリックごとに追加機能と削除機能を切り替えるブックマーク ボタンを実装する」という最終的な目標については、他の人がすでに十分なヒントを与えてくれています。

于 2012-11-13T22:19:21.117 に答える
1

現在のアプローチの問題は2つあります。

  1. .url プロパティは、リンクの URL ではなく、ドキュメントの URL を参照します
  2. 本当に変更したいのは、DOM の一部ではなく、JavaScript のイベント ハンドラーで実行されるアクションです。

必要な動作を得るには、コントローラーでこれを処理し、状態を追跡するために ajaxLink を少し変更する必要があると思います。

CHtml::ajaxLink($text, array('/core/bookmark/create'), array(
    'data' => array("id" => $id, "state"=>$("#bookmark-btn").hasClass("bookmark_on") ),
    'type' => 'GET',
    'success'=>'js:function(data){
        if (data.status == "success"){ 
            var bookmarkState = $("#bookmark-btn").hasClass("bookmark_on");
            if (!bookmarkState) {
                $("#bookmark-btn").addClass("bookmark_on").removeClass("bookmark_off");
                // Probably need some code here to update the link text as well
            } else {
                $("#bookmark-btn").addClass("bookmark_off").removeClass("bookmark_on");
                // Probably need some code here to update the link text as well
            }
        }
    }',
), array('id'=>'bookmark-btn', 'class' => 'bookmark_off'));  

次に、コントローラー (おそらく からcreateのようなより一般的なものに名前を変更しhandleBookmarkます) で、 の値を確認してから、既に記述した既存のまたはアクションをstate呼び出す必要があります。createdelete

別の方法として、jQuery を介してクライアント側でこれを行うこともできますが、カスタム トリガーとアクションを記述する必要があります (ほとんどの場合、 の値を読み取り、$("#bookmark-btn")そこで別の JavaScript パスをたどります)。これは、Yii の簡易メソッドを使用するのではなく、JavaScript を直接記述する必要があることを意味しますajaxLink

前述のように、これを行うより簡単な方法は、おそらくadddeleteリンクの両方をレンダリングし、必要に応じて可視性を切り替えることです。

于 2012-11-12T17:51:41.753 に答える