Языки шаблонов и виджеты ajax
У меня действительно нубский вопрос о виджетах ajax. Это действительно продолжение вопроса, который я задал недавно: виджеты ajax в пирамиде и хамелеоне
Если вы посмотрите на этот вопрос и содержимое файла account_login_widget.pt, вы увидите, что "виджет" использует синтаксис, такой как ${username}. Это снова работает для виджета входа в систему, которого на странице только один, но все изо всех сил пытается использовать этот "шаблон виджетов" для виджетов, которые могут существовать несколько раз на странице.
Теперь я хочу создать кнопку переключения Ajax. Кнопка должна быть настраиваемой: текст кнопки может меняться в зависимости от страницы, на которой она используется, и код обратного вызова также может быть изменен... опять же, в зависимости от страницы. Кроме того, несколько кнопок переключения должны существовать на одной странице.
2 вопроса:
Допустим, у меня есть список ресторанов на моей странице и кнопка "Мне нравится" рядом с каждым. Как правильно передать идентификатор ресторана вызову сервера 'post' (т. Е. Как передать переменные в виджет javascript?).
Допустим, на той же странице я хочу использовать тот же виджет кнопки переключения 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>
Спасибо!
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, и подписка является логическим значением, указывающим, подписан ли текущий пользователь на текущую "публикацию". Я идентифицирую каждую кнопку с помощью названия кнопки "sub" или "unsub", добавляя после него идентификатор сообщения, которое я отправляю / получаю в форме base36, и разделяю эти два имени подчеркиванием. Затем я использую JavaScript для извлечения идентификатора поста из идентификатора каждой кнопки.
function subscribe(obj) {
var id = $(obj).attr("id").split('_')[1];
$.post(
"/api/subscribe/",
{id: id, _csrf: _csrf},
function () {
$('#sub_' + id).hide();
$('#unsub_' + id).show();
}
);
}
У меня в принципе такая же функция для отписки. Обратите внимание, как я получаю идентификатор сообщения из атрибута идентификатора кнопки. / Api / subscribe / и / api / unsubscribe / route принимает только один параметр id и заставляет request.user подписываться на пост с этим идентификатором. Эти маршруты не будут работать, если request.user или _csrf не существует.
Моя версия намного короче и работает точно. Надеюсь, это поможет вам.
Для лайков против следующих я бы написал два шаблона и два набора функций javascript, предполагая, что они используют совершенно разные контроллеры. Если вы пытаетесь скопировать Facebook, где "Like", "Subscribe" и "Follow" - это одно и то же, то все, что вам нужно сделать, это сделать так, чтобы шаблон разрешал разные тексты:
<%def name="subscribe(post, subtitle='subscribe', unsubtitle='unsubscribe')">
...
<span ...>${subtitle}</span>
<span ...>${unsubtitle}</span>
</%def>