Django-Ajax “Uncaught ReferenceError: FOO is not defined”

Django-Ajax "Uncaught ReferenceError: FOO is not defined"

提问人:Viktor 提问时间:10/24/2023 最后编辑:Viktor 更新时间:10/24/2023 访问量:79

问:

我是 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

JavaScript Django AJAX

评论


答:

0赞 David 10/24/2023 #1

updateQuantity不在全局(窗口)作用域中定义,仅在特定函数中定义。所以不能像那样直接调用它。<button>

一种方法是将函数移出该匿名函数并移入全局范围:updateQuantity

<script>
  function updateQuantity(url) {
    //...
  }
</script>

由于所有这一切都是定义一个函数,因此它不需要等待事件。如果您确实想要/需要等待该事件,您可以手动将函数分配给对象:DOMContentLoadedwindow

<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-*idid
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')