更新模板数据后是否需要重新渲染页面 [英] Do I have to re-render my page after updating template data

查看:409
本文介绍了更新模板数据后是否需要重新渲染页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先我搜索并看到了另一个答案,但不能满足我的需要。

First I have searched and seen another answer, but it doesn't address my need.

我正在尝试使用jQuery / AJAX从我的HTML发布数据以更新也在我的HTML上的列表。

I am trying to POST data using jQuery/AJAX from my HTML to update a list that is also on my HTML.

当我第一次渲染模板时,它有两个列表组容器,其中左容器是预先填充的。

When I first rendered my template, it had two list-group containers of which the left container is pre populated.

两个容器

用户在左侧容器中做出的选择确定了右侧容器的列表组数据。

The choice made user makes on the left container determines the list group data of the right container.

我想发回后端Python(服务器),该服务器从左侧容器中选择用户,以便为第二个容器(右侧)填充适当的列表。 ) 容器。这就是为什么我使用使用jQuery / AJAX的POST方法发送用户选择的原因。

I wanted to send back to the backend Python (server) which selection the user made from the left container, so that I may populate the appropriate list for the second (right) container. This is why I used the POST method using jQuery/AJAX to send users selection.

HTML

这是 HTML的plnkr

Here is a Plnkr of the HTML

以下是 WORKS 的jQuery / AJAX实现。它将数据发送回Python (到我的views.py)

Below is the jQuery/AJAX implementation which WORKS. It sends data back to Python (to my views.py):

JS / jQuery / AJAX:

<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script>
    $("#leftContainer > a").click(function(event){
        event.preventDefault();
        $("#leftContainer > a").removeClass("active");
        $(this).addClass("active");

        var leftDataSet = parseInt($(this).attr("data-set"));        
        var item_selected = $(this).text();
        var item_index = $(this).attr("id")   //Users selection to send

        $.ajax({
            type:'POST',
            url:"home/view_results/onclick/",
            data:{
                selected_item:item_index,
                csrfmiddlewaretoken:"{{ csrf_token }}"
            },
            dataType:"text",
            success: function(){$('#message').html("<h3>Data Submitted!</h3>") }
        })        
    });

    $("#rightContainer > a").click(function(event){
        event.preventDefault();
        $(this).toggleClass("active");
    });
</script>

views.py

#app/views.py
from django.shortcuts import render
class View_Items():

   def render_view_items(self, request, shopid):
      item_history = self.get_item_list(shopid)     #Fetches a list
      return render(request, 'view_results/View_items.html',{
           'item_list':item_history,
        })

urls.py

#app/urls.py
from django.urls import path, re_path
from . import views
results = views.View_Items()
urlpatterns=[
        ...
        re_path(r'view_results/(?P<shopid>\w+)$', results.render_view_items, name = 'view_items'),
        re_path(r'view_results/onclick/$', results.render_view_items_again, name = 'view_results_new'),  # NEW
]

我的问题是:

现在,我已经在views.py将AJAX数据返回到我的Python后端,是否需要重新渲染页面以在HTML中填充Right容器的列表组项目?或者可以更新列表而不必重新渲染。如果是这样,为什么我在 NOT 下建议的重新渲染功能更新HTML的 RIGHT容器?更新Right容器是需要选择左侧容器的目标。

now that I have the AJAX data returned back to my Python backend at views.py, do I have to re-render my page to populate the Right container's list group items in my HTML? Or is it possible to update the list without having to re-render. If so, why is my proposed re-render function below NOT updating the RIGHT container of my HTML? Updating the Right container is the objective which required the selection choice of left container.

我对views.py

#app/views.py
def render_view_items_again(self, request):
    selected_item_by_user = request.POST.get('selected_item')
    # print(selected_item_by_user)
    models = self.get_all_models(selected_item_by_user)  #Fetches a list.
    # print(models)                     #Tested if my list is populated.
    return render(request, 'view_results/View_items.html',{
        'model_list':models,
        })


推荐答案

完全有可能填充正确的容器,而无需重新加载页面。

It is totally possible to fill the right container, without having to reload your page.

通常要做的是将功能从views.py划分为第一个渲染的情况,以及从AJAX POST返回时的情况。在您的情况下,views.py类似于:

What is usually done is to divide the function from views.py into the case of the first render and when you return from an AJAX POST. In your case, the views.py will be something like:

if request.method == 'POST': # Returning from AJAX
    selected_item_by_user = request.POST.get('selected_item')
    models = self.get_all_models(selected_item_by_user)  #Fetches a list.
    return JsonResponse({'completed': "ok", 'list': models})

else:  # First time render
    item_history = self.get_item_list(shopid)     #Fetches a list
    return render(request, 'view_results/View_items.html',{
         'item_list':item_history,
       })

如您所见,我只是第一次渲染模板。当您从AJAX返回时,我仅致电 JsonResponse 。将以下导入添加到您的代码中:

As you can see, I have only rendered the template the first time. When you get back from AJAX, I only call JsonResponse. Add the following import to your code:

from django.http import JsonResponse

请注意,根据列表的构建方式(未提供详细信息),您需要对其进行编码可编码地

Please be aware that depending on how is built your list (you have not provided the details), you will need to encode it accodingly.

然后,在成功函数,您可以轻松地使用列表(进行修改以填充正确的容器):

Then, in the success function of your AJAX method, you can easily use the list (adapt it so that you fill the right container):

success: function(data){console.log(data.list)}

因此,将在不进行页面重新渲染/刷新的情况下填充正确的容器。

Hence, the right container will be filled without doing a re-render/refresh of the page.

现在我看到你了还会重定向到您的AJAX方法中的其他网址。如果您不想刷新,请按以下步骤在AJAX方法中设置网址:

Now I see that you are also redirecting to a different url in your AJAX method. If you want not to refresh, set your url in the AJAX method as follows:

$.ajax({
    type:'POST',
    url: window.location.href,
    data:{
        selected_item:item_index,
        csrfmiddlewaretoken:"{{ csrf_token }}"
    },
    dataType:"text",
    success: function(){$('#message').html("<h3>Data Submitted!</h3>") }
})  

所以您只需在 urls.py

So you only need one url in the urls.py file too.

我也不知道您正确的容器的HTML代码,但是如果它是列表 ul (假设它具有 id = list_conditions ),则可以按如下所示将项目添加到正确的容器中:

I do not know the HTML code of your right container, but if it is a list ul (let's suppose that it has an id=list_conditions), you could add an item to the right container as follows:

// Get where I should add the index
let ul=document.getElementById("list_conditions");
// Create a new child
let li=document.createElement("li");
li.setAttribute("class", "list-group-item list-group-item-secondary");              
li.appendChild(document.createTextNode(data.list[0])); // Here you can replace by the index you need from the list
ul.appendChild(li);

这篇关于更新模板数据后是否需要重新渲染页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆