Использование разделов в частичных представлениях в MVC 4.0

Я хочу включать скрипты в мои частичные представления, когда у меня есть случаи, когда мне нужно инициализировать jQuery ui для определенных элементов. Он действительно принадлежит частичной, а не содержательной странице или макету.

Предположительно, есть способ сделать это в MVC 4, но я не могу найти никакой информации об этом.

Ответ 1

У меня тоже была аналогичная проблема. Надеюсь это поможет. Мы хотели иметь представление, которое содержит общую секцию заголовка, которая отображает некоторые данные и другой раздел, которые должны динамически меняться при нажатии ссылки на нашей странице. (что-то похожее на вкладку) Поскольку мы не хотели повторно загружать секцию заголовка несколько раз, мы решили иметь контейнерный вид и div-держатель места, который будет использоваться для загрузки частичного представления динамически, когда мы нажимаем на ссылку ajax. Однако частичные представления, загруженные в держатель места, имели много javascript-кода, и мы не могли включить весь код, который использовался разными частичными представлениями в один файл javascript, и ссылаться на него из представления контейнера, поскольку существуют некоторые конфликтующие функции, Введение пространств имен для исправления этой проблемы также было не очень эффективным, поскольку вся логика javascript все равно была загружена без необходимости. Сделав немного поискового запроса, я понял, что раздел script в частичном представлении не будет работать. Я попытался определить раздел в моем представлении, используя @RenderSection ( "partialScripts", required: false) безуспешно, поскольку RenderSection работает только в макете. Ниже приводится подход, который я принял для преодоления этой проблемы. раздел сценариев, который определен в макете, может содержать любую действительную разметку. поэтому я решил иметь div, который поможет мне динамически загружать сценарии в разделе сценариев моего представления контейнера. Обработчик событий OnSuccess ссылки действия использовался для динамического добавления сценариев. Вот код для моего контейнера.

<ul>
    <li>
        @Ajax.ActionLink("Partial One", "PartialOne", ajaxOptions: new AjaxOptions
                     {
                         HttpMethod = "Get",
                         InsertionMode = InsertionMode.Replace,
                         UpdateTargetId = "container",
                         OnSuccess = "loadScriptsDynamically('PartialOne')"
                     })
    </li>
    <li>
        @Ajax.ActionLink("Partial Two", "PartialTwo", ajaxOptions: new AjaxOptions
                     {
                         HttpMethod = "Get",
                         InsertionMode = InsertionMode.Replace,
                         UpdateTargetId = "container",
                         OnSuccess = "loadScriptsDynamically('PartialTwo')"
                     })
    </li>
</ul>

<div id="container">
</div>

@section scripts
{
    <script src="@Url.Content("~/Scripts/app/Container.js")"></script>
    <div id="dynamicScripts"
         data-partial-one="@Url.Content("~/Scripts/App/PartialOne.js")"
         data-partial-two="@Url.Content("~/Scripts/App/PartialTwo.js")">
    </div>
}

Код из класса контроллера

    public PartialViewResult PartialOne()
    {
        return PartialView("_PartialOne");
    }

    public PartialViewResult PartialTwo()
    {
        return PartialView("_PartialTwo");
    }

Файл Container.js содержит логику, которая будет динамически загружать необходимые сценарии для разных частичных представлений.

function loadScriptsDynamically(name) {
    var script = document.createElement('script');
    var dynamicScriptsDiv = document.getElementById('dynamicScripts');
    var dynamicScriptDivJQuery = $('#dynamicScripts');
    dynamicScriptDivJQuery.empty();
    if (name === 'PartialOne') {
        script.src = dynamicScriptDivJQuery.data('partial-one');
        dynamicScriptsDiv.appendChild(script);
    } else if (name === 'PartialTwo'){
        script.src = dynamicScriptDivJQuery.data('partial-two');
        dynamicScriptsDiv.appendChild(script);
    }
}

Мы не можем использовать jQuery для добавления элемента script в div из-за некоторых ограничений. Но мы можем использовать какой-то старомодный код javascript для создания элемента script и добавить его в dynamicScriptsDiv. Обратите внимание, что я обращаюсь к путям script, которые я ранее прикреплял к dynamicScriptsDivusing, используя некоторые атрибуты данных, поскольку наше приложение MVC запускается на сервере IIS, и мы не хотели их жестко кодировать.

Присоединение к событиям после динамического загрузки script стало нашей следующей задачей. Используя функцию немедленного вызова, я смог зарегистрировать весь код привязки события и любую логику инициализации, которую я должен выполнить, используя следующий код.

(function initPartialOne() {
    $('#myButton').click(function() {
        setLabelText();
    });
})();

function setLabelText() {
    $('#myLabel').text('One was clicked');
}

И, наконец, код для одного из моих частичных представлений.

<label id="myLabel">[Message]</label>
<input type="button" id="myButton" value="Click me partial one"/>

Ответ 2

Это невозможно в ASP.NET MVC 3 (См. второй комментарий в этом сообщении). Разделы могут использоваться только в (главном) представлении, а не в частичных.

В настоящее время я не могу найти какие-либо ресурсы в соответствии с MVC версии 4, но короткий тест в Visual Studio также не выполняется для MVC 4, если вы не отрисуете весь частичный вид внутри раздела.

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