2011-12-27 57 views
1

我对ajax小部件有一个真正的noob问题。这实际上是我刚才问的一个问题的延伸:ajax widgets in pyramid and chameleon模板语言和ajax小部件

如果你看这个问题和文件account_login_widget.pt的内容,你会看到'widget'使用类似$ {username}的语法。这再次适用于一个页面上只有一个登录窗口小部件,但所有地狱崩溃尝试使用这个“窗口小部件模式”的小部件,可以在页面上多次存在。

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

2个问题:

  1. 比方说,我有我的网页上的餐馆和“喜欢”按钮旁边的每个列表。将餐厅ID传递给'post'服务器调用的正确方法是什么(即:如何将变量传递给javascript部件?)。

  2. 在同一页上,假设我想使用相同的ajax切换按钮小部件,但在不同的上下文中。比方说,在同一页上,我也有一个人名单,我想'追随'他们。将按钮文本变量传递到窗口小部件并更改post服务器调用行为的正确方法是什么? (即:在问题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> 

谢谢!

回答

1

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

在控制器中,我有一个创建订阅按钮的模板。我没有在单个按钮上更改名称,而是制作了两个隐藏(或禁用)按钮。这实在不应该比你目前所做的更多时间。使用真子(不熟悉的变色龙),模板功能是:

<%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,并订阅是一个布尔告诉我当前用户是否订阅了现行“后”。我使用按钮名称“sub”或“unsub”来标识每个按钮,后缀为以base36格式发送/接收的帖子的ID,并将这两个名称用下划线分隔。然后我使用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不存在,这些路由将不起作用。

我的版本非常短,工作肯定。希望这可以帮助你。

对于喜欢vs之后,我会写两个模板和两组javascript函数,假设他们使用完全不同的控制器。如果你想复制的Facebook在那里顶,订阅,并遵循都是同样的事情,那么所有你需要做的是模板允许不同的文本:

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

感谢您的详细答复。这比我想要达到的要少一些,但我最终可能只是走这条路。 – lostdorje 2012-01-02 02:13:01