Нужно ли повторно визуализировать мою страницу после обновления данных шаблона? - PullRequest
0 голосов
/ 30 ноября 2018

Сначала я искал и видел другой ответ , но он не отвечает моим потребностям.

Я пытаюсь POST-данные, используя jQuery / AJAX из моего HTML, чтобы обновить списокэто также в моем HTML.

Когда я впервые отображал свой шаблон, в нем было два контейнера группы списков, из которых левый контейнер предварительно заполнен.

два контейнера

Выбор , сделанный пользователем на левом контейнере, определяет данные группы списков правого контейнера .

Я хотел отправить обратно на внутренний сервер Python (сервер), который выбрал пользователь из левого контейнера, чтобы я мог заполнить соответствующий список для второго (правого) контейнера.Вот почему я использовал метод POST, используя jQuery / AJAX для отправки выбора пользователей.

HTML

Вот Plnkr HTML

Ниже приведен jQuery / AJAXреализация которого РАБОТАЕТ .Он отправляет данные обратно в Python (в мои 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
]

Мой вопрос:,

теперь, когда у меня есть данные AJAX, возвращенные обратно в мой бэкэнд Python по адресу views.py, нужно ли повторно визуализировать мою страницу, чтобы заполнить элементы группы списков Правого контейнера в моем HTML?Или можно обновить список без повторной визуализации.Если это так, почему моя предложенная функция повторного рендеринга ниже НЕ обновляет ПРАВЫЙ контейнер моего HTML?Обновление Правого контейнера - это цель, которая требовала выбора левого контейнера.

Добавление, которое я сделал к 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,
        })

1 Ответ

0 голосов
/ 30 ноября 2018

Вполне возможно заполнить нужный контейнер без перезагрузки вашей страницы.

Что обычно делается, это разделить функцию из views.py на случай первого рендера и когда вы вернетесьиз поста AJAX.В вашем случае views.py будет выглядеть примерно так:

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.Добавьте следующий код в ваш код:

from django.http import JsonResponse

Обратите внимание, что в зависимости от того, как составлен ваш список (вы не предоставили подробности), вам нужно будет его закодировать согласно 1011 *.

Затем в функции success вашего метода AJAX вы можете легко использовать list (адаптировать его так, чтобы заполнить нужный контейнер):

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

Следовательнонужный контейнер будет заполнен без повторного рендеринга / обновления страницы.

Edit 1

Теперь я вижу, что вы также перенаправляете на другой URL в вашем методе AJAX.Если вы не хотите обновлять, установите ваш URL в методе AJAX следующим образом:

$.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>") }
})  

Так что вам нужен только один URL в файле urls.py.

Я не знаюHTML-код вашего правильного контейнера, но если это список ul (предположим, что он имеет id=list_conditions), вы можете добавить элемент в нужный контейнер следующим образом:

// 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);
...