提问人:Viktor 提问时间:10/24/2023 最后编辑:Viktor 更新时间:10/24/2023 访问量:79
Django-Ajax “Uncaught ReferenceError: FOO is not defined”
Django-Ajax "Uncaught ReferenceError: FOO is not defined"
问:
我是 AJAX 的新手。想要调用 django 视图以更新页面上的项目数量和数量。 我有一个模板
...
{% for item in items %}
<div id="quantity">{{ item.quantity }}</div>
<button onclick="updateQuantity('parts/quotes/ajax/increase-item/')">+</button>
...
<script>
function docReady(fn) {
if (document.readyState === "complete" || document.readyState === "interactive") {
setTimeout(fn, 1);
} else {
document.addEventListener("DOMContentLoaded", fn);
};
};
docReady(function() {
function updateQuantity(url) {
fetch(url, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest",
}
})
.then(response => response.json())
.then(data => {
document.getElementById("quantity").innerHTML = data;
});
}
});
</script>
还有一个观点:
def increase_quote_item_ajax(request):
is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
if is_ajax:
if request.method == 'GET':
item = QuoteItem.objects.get(id=pk)
item.quantity += 1
item.save(update_fields=['quantity'])
return JsonResponse({'data': item.quantity})
return JsonResponse({'status': 'Invalid request'}, status=400)
else:
return HttpResponseBadRequest('Invalid request')
但是当我点击+按钮时,我得到
Uncaught ReferenceError: updateQuantity is not defined
为什么我的函数没有注册?
更新:
根据 David 的建议:
{% for item in items %}
<span>{{ item.quantity }}</span><button class="increase-button" data-foo=""{{ item.get_increase_url_ajax }}"">+</button>
...
<script>
const buttons = document.getElementsByClassName('quantity-button');
for (const button of buttons) {
button.addEventListener('click', function (e) {
fetch(e.target.dataset.foo, {
method: "GET",
headers: {
"X-Requested-With": "XMLHttpRequest",
},
})
.then(response => response.json())
.then(data => {
button.previousSibling.innerHTML = data['quantity'];
});
});
}
</script>
将 in-fetch 请求传递给 django 视图的正确方法是什么?我认为我不应该在标题中这样做。id
答:
0赞
David
10/24/2023
#1
updateQuantity
不在全局(窗口)作用域中定义,仅在特定函数中定义。所以不能像那样直接调用它。<button>
一种方法是将函数移出该匿名函数并移入全局范围:updateQuantity
<script>
function updateQuantity(url) {
//...
}
</script>
由于所有这一切都是定义一个函数,因此它不需要等待事件。如果您确实想要/需要等待该事件,您可以手动将函数分配给对象:DOMContentLoaded
window
<script>
docReady(function() {
window.updateQuantity = function (url) {
//...
};
});
</script>
或者,不要直接在标记中调用该函数,而是在定义函数的位置分配一个单击处理程序。例如,如果您给出 :<button>
<button>
id
<button id="update-button">+</button>
然后,在定义函数时,您可以使用该函数(或您喜欢的任何选择器,这只是例如)将单击处理程序附加到按钮:id
<script>
docReady(function() {
const url = 'parts/quotes/ajax/increase-item/';
function updateQuantity() {
//...
}
document.querySelector('#update-button').addEventListener('click', updateQuantity);
});
</script>
评论
0赞
Viktor
10/24/2023
我明白了我的问题出在范围上。然后是一个后续问题:由于我有一个创建多个按钮的 for 循环,我如何将 {{ item.id }} 传递给 updateQuantity 函数以将其传递给 Django 视图?
1赞
David
10/24/2023
@Viktor:可以将按钮上的值作为属性包含,然后从引发事件的按钮中提取这些属性值。下面是使用属性的快速演示。顺便说一句......如果你在一个循环中输出相同的元素,那么你会遇到额外的问题,因为值应该是唯一的。data-*
data-*
id
id
0赞
Viktor
10/24/2023
我已经更新了代码(见上文),但是将 id 发送回 django 视图的正确方法是什么(我假设不在标题中)
0赞
David
10/24/2023
@Viktor:这可能取决于您的后端代码。它如何期望这个价值?在查询字符串上?在表格中?在 JSON 请求正文中?别的?另请注意,原始代码和原始问题/疑问实际上与此没有任何关系。如果您遇到与原始问题无关的新问题,那么可能需要提出新问题。
0赞
Viktor
10/24/2023
我的意思是我可以在标头中发送 ithe id,并使用 .但这似乎不是一个预期的方式。什么是合适的 fetch 字典?"pk": e.target.dataset.foo,
request.headers.get('pk')
评论