1

私は ajax ウィジェットについて本当に初歩的な質問があります。これは、私が少し前に尋ねた質問の拡張です:ピラミッドとカメレオンの ajax ウィジェット

この質問とファイル account_login_widget.pt の内容を見ると、「ウィジェット」が ${username} のような構文を使用していることがわかります。これは、ページに 1 つしかないログイン ウィジェットに対しては再び機能しますが、ページに複数回存在する可能性のあるウィジェットに対してこの「ウィジェット パターン」を使用しようとすると、すべてがうまくいきません。

次に、ajax トグル ボタンを作成します。ボタンは構成可能である必要があります。ボタンのテキストは、使用されているページに応じて変更できます。また、コールバック コードも変更できる必要があります...これもページによって異なります。さらに、複数のトグル ボタンが同じページに存在できる必要があります。

2 つの質問:

  1. 私のページにレストランのリストがあり、それぞれの横に「いいね」ボタンがあるとしましょう。レストラン ID を「post」サーバー呼び出しに渡す正しい方法は何ですか (つまり、どのように変数を JavaScript ウィジェットに渡しますか?)。

  2. 同じページで、同じ ajax トグル ボタン ウィジェットを別のコンテキストで使用したいとします。たとえば、同じページに人のリストもあり、それらを「フォロー」したいとします。ボタン テキスト変数をウィジェットに渡し、ポスト サーバー呼び出しの動作を変更する正しい方法は何ですか? (つまり: 質問 1 では restaurant.like() を呼び出したいかもしれませんが、質問 2 では person.follow() を呼び出したいと思います)

ウィジェットを表示するサンプルコードを次に示します...

<script type="text/javascript">
// plugin implementation
(function($) {
$.fn.create_ajax_toggle_button = function(csrf, name, toggle_on, url, on_text, off_text) {
    return this.each(function() {
        var anchor = $('<a></a>');
        anchor.appendTo(this);

        $(anchor).button();

        $(anchor).toggle_ajax_button_text(toggle_on, on_text, off_text);

        $(anchor).click(function(e) {
            var form_data = '_csrf=' + csrf + '&name=' + name + '&toggle_on=' + toggle_on;

            $.post(url, form_data, function(response) {
                $.fn.toggle_ajax_button_text();
            });
        });
    });
};

$.fn.toggle_ajax_button_text = function(toggle_on, on_text, off_text) {
    if (toggle_on == 'True') {
        $(this).toggleClass('ui-state-active');
        $(this).text(on_text);          
    } else {
        $(this).text(off_text);             
    }
};
})(jQuery);

// Define the entry point    
$(document).ready(function() {
    // YUCK!!! I really shouldn't be/can't using ${name} templating
    // syntax like this.  Doing this means the JS code needs to be
    // loaded over and over again for each item in the list.  This
    // just doesn't work.  :-(
    $('.ajax_toggle_button_div_${name}').create_ajax_toggle_button('${csrf}', '${name}',     '${toggle_on}', '${url}', '${on_text}', '${off_text}');
});
</script>

<div class="ajax_toggle_button_div_${name}"></div>

ありがとう!

4

1 に答える 1

1

いいねボタンのためだけにあまりにも多くの作業を行っているように感じます。私は JavaScript が嫌いなので、特にドキュメントの読み込み時に、ユーザーのブラウザーに遅れが生じるため、可能な限り避けようとしています。「サブスクリプション」に使用するものを投稿します。うまくいけば、何らかの形で役立ちます.

コントローラーには、サブスクリプション ボタンを作成するテンプレートがあります。1 つのボタンの名前を変更する代わりに、2 つのボタンを作成し、1 つを非表示 (または無効) にします。これには、現在行っている作業よりも多くの時間がかかることはありません。Mako (Chameleon には詳しくない) を使用すると、テンプレート関数は次のようになります。

<%def name="subscribe(post)">
% if request.user:
<% subscribe = Bookmark_C.check_subscribed(request.user.id, post.id) %>
<span class="pstnm">${Bookmark_C.get_num_subscribers(post.id)}</span>
<span class="pstbtn${' hide' if subscribe else ''}" id="sub_${post.base36}" onclick="subscribe(this)">subscribe</span>
<span class="pstbtn${' hide' if not subscribe else ''}" id="unsub_${post.base36}" onclick="unsubscribe(this)">unsubscribe</span>
% endif
</%def>

現在のユーザー オブジェクトは request.user に格納され、subscribe は現在のユーザーが現在の「投稿」を購読しているかどうかを示すブール値です。各ボタンに「sub」または「unsub」というボタン名を付け、base36 形式で送受信する投稿の ID を後置し、これら 2 つの名前をアンダースコアで区切ります。次に、JavaScript を使用して、各ボタンの ID から投稿の ID を抽出します。

function subscribe(obj) {
  var id = $(obj).attr("id").split('_')[1];
  $.post(
    "/api/subscribe/",
    {id: id, _csrf: _csrf},
    function () {
      $('#sub_' + id).hide();
      $('#unsub_' + id).show();
    }
  );
}

私は基本的に購読解除のために同じ機能を持っています。ボタンの ID 属性から投稿の ID を取得する方法に注目してください。/api/subscribe/ および /api/unsubscribe/ ルートは、1 つのパラメーター id のみを取り、request.user にその id を持つ投稿を購読させます。request.user または _csrf が存在しない場合、これらのルートは機能しません。

私のバージョンははるかに短く、確実に機能します。うまくいけば、これはあなたを助けます。

like と follow については、2 つのテンプレートと 2 つの JavaScript 関数のセットを記述します。これらはまったく異なるコントローラーを使用すると仮定します。Like、Subscribe、Follow がすべて同じものである Facebook をコピーしようとしている場合は、テンプレートで異なるテキストを許可するだけで済みます。

<%def name="subscribe(post, subtitle='subscribe', unsubtitle='unsubscribe')">
...
<span ...>${subtitle}</span>
<span ...>${unsubtitle}</span>
</%def>
于 2011-12-28T02:25:42.933 に答える