Я пытаюсь обновить определенную часть моей страницы с помощью AJAX и JQuery (в Django). Как я могу заставить его повторно отображать только div, а не всю страницу.
// In my template
var tag_cloud_floor = function(floor) {
$.ajax({ url: "/{{ user }}/{{ tag }}/",
data: {tag_cloud_floor: floor},
type: 'POST',
success: function(data) {
$('#tag_cloud).html(data);
},
});
};
Вот мой взгляд.
@login_required
def tag_page(request, username, tag):
if username == request.user.username:
tags = request.user.userprofile.tag_set.all()
if request.is_ajax() and request.POST:
floored_tags = []
for t in tags:
if t.item_set.all().count() >= int(request.POST['tag_cloud_floor']):
floored_tags.append(t)
tags = floored_tags
tag = Tag.objects.get(title=tag)
items = tag.item_set.all()
return render_to_response("tag_page.html", { 'user': request.user ,
'tag': tag,
'tags': tags,
'items': items })
else:
return HttpResponseRedirect('/' + request.user.username + '/')
В настоящее время он помещает всю html-страницу в div #tag_page. Я хочу, чтобы он заменил старый #tag_page div новым #tag_page div. Если я заменил $('#tag_cloud').html(data);
на $('body').html(data);
, он обновит всю страницу до того, как она должна быть, но я считаю, что обновление всей страницы является отходом.
Если есть лучший способ сделать это, дайте мне знать.
Во-первых, похоже, что ваш код поврежден - это не действительная инструкция Javascript/jQuery:
$('#tag_cloud).html(data);
Вам нужно добавить отсутствующую цитату:
$('#tag_cloud').html(data);
Что касается обновления только одного div
, я бы извлек содержимое этого div в отдельный шаблон my_div.html
, включив его в шаблон главной страницы, используя {% include "my_div.html" %}
. Затем, в моем представлении AJAX, я бы отобразил и вернул только то, что вынесло my_div.html
.
Используйте load:
$('#tag_cloud').load(' #tag_cloud')
(Обратите внимание на начальное пространство в параметре load
, это указывает пустую строку [которая оценивает текущую страницу] в качестве источника и "#tag_cloud" в качестве загружаемого фрагмента)
Это фактически загрузит #tag_cloud (включая его внешний html) в #tag_cloud, так что вы существенно получите следующую структуру в DOM:
<div id="tag_cloud">
<div id="tag_cloud">
<span>tag</span> ...
Чтобы исправить это, просто unwrap
дети:
$('#tag_cloud').load(' #tag_cloud', function(){$(this).children().unwrap()})
О, кстати... вы можете попробовать это здесь, на SO! Просто вставьте следующее в свою консоль Firebug и посмотрите, как перезагрузка боковой панели. Вы заметите, что код сценария просунул; что jQ HTML-фильтры безопасности отключают элементы <script>
для вас (что может раздражать порой).
$('#sidebar').load(' #sidebar', function(){$(this).children().unwrap()})
load
.
В нашем проекте у нас было слишком много отдельных представлений Ajax, что имеет смысл писать промежуточное программное обеспечение и повторно использовать одни и те же представления. Недавно я создал приложение которое позволяет клиенту запрашивать части любой страницы.
Скажем, страница /usual_page/
имеет этот шаблон:
{% extends "another_template.html" %}
{% block title %}Usual page{% endblock %}
{% block content %}...{% endblock %}
{% block my_widget %}widget code{% endblock %}
Если вы установите промежуточное программное обеспечение и сделаете запрос GET, например /usual_page/?partial=my_widget
, он отправит клиенту эти данные:
{"blocks": {"my_widget": "widget code"}}
Или, если вы выполните /usual_page/?partial=title,content
, он отправит следующее:
{"blocks": {"title": "Usual page", "content": "..."}}
Также можно запросить другие блоки, которые находятся в родительском шаблоне. Неважно, где находится блок в иерархии, имеет значение только то, что оно присутствует на обычной странице (без параметра ?partial
).
В репозиторий BitBucket у меня есть демонстрационный проект, в котором есть модуль, который автоматизирует работу. Он позволяет использовать метод History.pushState и загружать части страниц и вставлять их в документ.