2011-12-27 49 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