Навигация по Django: расширяется против innerHTML

У меня есть одно веб-приложение, которое имеет боковое меню навигации, чтобы выбрать, что видеть в основном блоке контента. Важно предупредить вас, что количество элементов этой боковой панели изменяется динамически. Файл, содержащий эту боковую панель, называется base.html.

Поскольку у меня есть один отдельный шаблон для каждого элемента боковой панели (a.html, b.html и т. Д.)... Какой наилучший способ загрузить его содержимое в основной блок содержимого?

Опция A (Расширение):

Файл: base.html

<nav id="sidebar">
    <div class="navbar-default sidebar" role="navigation">
        <div class="sidebar-nav navbar-collapse navbar-ex2-collapse">
            <ul class="nav in" id="side-menu">
                {% for submodule in submodules %}
                    <li>
                        <p id="{{ submodule }}"><i class="fa fa-table fa-fw"></i> {{ submodule }}</p>
                    </li>
                {% endfor %}
            </ul>
        </div>
    </div>
</nav>
<div id="page-wrapper">
    {% block content %} {% endblock %}
</div>

Файл: a.html

{% extends 'base.html' %}
{% load staticfiles %}
{% load i18n %}

{% block content %}
    <whatever...>

{% endblock %}

Опция B (innerHTML):

Файл: base.html

<nav id="sidebar">
    <div class="navbar-default sidebar" role="navigation">
        <div class="sidebar-nav navbar-collapse navbar-ex2-collapse">
            <ul class="nav in" id="side-menu">
                {% for submodule in submodules %}
                    <li>
                        <p id="{{ submodule }}"><i class="fa fa-table fa-fw"></i> {{ submodule }}</p>
                    </li>
                {% endfor %}
            </ul>
        </div>
    </div>
</nav>
<div id="page-wrapper">
    <div id="submodule-view" class="row">
        <!-- View content will be included here --->
    </div>
</div>

<script>
    ...
    // For every sidebar button dinamically generated, 'loadActiveSubmodule'
    // function gets linked to its click event.
    var theParent = document.querySelector("#side-menu");
    theParent.addEventListener("click", loadActiveSubmodule, false);

    // The selected submodule content is displayed when its button is clicked.
    function loadActiveSubmodule(e) {
        if (e.target !== e.currentTarget) {
            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
            $.ajax({
                datatype: 'json',
                data: ...,
                url: ...,
                type: 'post',
                success: function(htmlResult){
                    document.getElementById('submodule-view').innerHTML=htmlResult;
                }
            });
        }
        e.stopPropagation();
    }
</script>

а потом в views.py ...

if request.is_ajax():
    ...
    url = ...
    context = ...

    return render(request, url, context)

Я закодировал оба варианта и пока предпочту второй вариант, потому что он кажется более чистым, поскольку мне не нужно устанавливать столько URL-адресов, сколько у меня есть элементы боковой панели. Эта навигация также работает быстрее, поскольку только часть веб-страницы перезагружается.

НО, основная проблема, которую я обнаружил, заключается в том, что функции javascript, которые закодированы внутри каждого файла шаблона (например, a.html), не работают с innerHTML (функции не определены), несмотря на то, что их код возвращается методом рендеринга Django. Кто-нибудь знает почему?

Возможным обходным путем для этого может быть разделение функций javascript в другом файле и загрузка этого файла по мере необходимости, но было бы здорово (по крайней мере, намного проще) заставить его работать сразу.

заранее спасибо

1 ответ

Упомянутая проблема с кодом javascript может быть решена простой заменой следующей строки:

document.getElementById('submodule-view').innerHTML=htmlResult;

От:

$("#submodule-view").html(htmlResult);

Я нашел это в следующем посте: Как заменить innerHTML элемента div с помощью jQuery?

Этот пост также может помочь понять разницу между этими двумя строками: JQuery html () и innerHTML

Благодарю.

Другие вопросы по тегам