模板语言和ajax小部件

时间:2011-12-27 06:28:12

标签: javascript python ajax pyramid chameleon

我对ajax小部件有一个非常noob的问题。这真的是我刚才问过的一个问题的延伸:ajax widgets in pyramid and chameleon

如果您查看此问题以及文件account_login_widget.pt的内容,您会看到'小部件'使用类似$ {username}的语法。这对于一个登录小部件再次起作用,其中只有一个在页面上,但是所有地狱都试图将这个“小部件模式”用于可以在页面上多次存在的小部件。

现在我想创建一个ajax切换按钮。该按钮应该是可配置的:按钮的文本可以根据其使用的页面而改变,并且回调代码也应该能够改变...再次取决于页面。此外,多个切换按钮应该能够存在于同一页面上。

2个问题:

  1. 假设我的页面上有一个餐馆列表,每个旁边都有一个“赞”按钮。将餐馆ID传递给'post'服务器调用的正确方法是什么(即:如何将变量传递给javascript小部件?)。

  2. 在同一页面上,假设我想使用相同的ajax切换按钮小部件,但是在不同的上下文中。让我们说,在同一页面上,我也有一个人名单,我想“跟随”他们。将按钮文本变量传递到窗口小部件并更改后服务器调用行为的正确方法是什么? (即:问题1可能我想打电话给restaurant.like(),但问题2我想打电话给person.follow()

  3. 以下是一些显示小部件的示例代码......

    <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>
    

    谢谢!

1 个答案:

答案 0 :(得分:1)

我觉得你只是为了一个类似的按钮做了太多的工作,我讨厌javascript所以我尽量避免它,特别是在文档加载,因为它滞后于用户的浏览器。我将发布我用于“订阅”的内容,希望它能以某种方式帮助你。

在控制器中,我有一个创建订阅按钮的模板。我没有更改单个按钮上的名称,而是制作两个按钮,其中一个隐藏(或禁用)。这真的不应该花费你现在的时间。使用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是一个布尔值,告诉我当前用户是否订阅了当前的“post”。我用按钮名称“sub”或“unsub”对每个按钮进行ID,后缀为帖子的ID,我以base36形式发送/接收,并用下划线分隔这两个名称。然后我使用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 / route只接受一个参数id,并使request.user订阅具有该id的帖子。如果request.user或_csrf不存在,这些路由将不起作用。

我的版本更短,确实有效。希望这会对你有所帮助。

对于喜欢和关注,我会写两个模板和两组javascript函数,假设他们使用完全不同的控制器。如果您正在尝试复制Facebook,其中Like,Subscribe和Follow都是相同的,那么您需要做的就是让模板允许不同的文本:

<%def name="subscribe(post, subtitle='subscribe', unsubtitle='unsubscribe')">
...
<span ...>${subtitle}</span>
<span ...>${unsubtitle}</span>
</%def>