Как инкапсулировать повторно используемый «элемент управления» для представлений ASP.NET MVC 3 + Razor - PullRequest
4 голосов
/ 27 ноября 2010

Я ищу рекомендации по созданию многоразового «элемента управления» для использования в нескольких представлениях MVC 3. Я мог бы создать вспомогательный метод расширения Html (программно или с помощью декларативных помощников в бритве) или создать частичное представление.

Хитрость, в моем случае, заключается в том, что мне нужно сделать больше, чем просто сбросить некоторый HTML-код именно в том месте, где представление вызывает вспомогательный / частичный. Помимо размещения некоторой HTML-разметки в этом месте, мне также нужно добавить некоторый код JavaScript, чтобы он работал. Обычно я бы поместил этот код в другое место на странице (например, внизу). Это, конечно, строго не требуется. Также обратите внимание, что JavaScript не является специфичным для экземпляра элемента управления. Другими словами, можно написать javascript, который находит все экземпляры разметки элемента управления HTMl на странице и «активирует» ее соответствующими событиями и т. Д.

Я подумал о нескольких возможностях.

  1. Поместите вспомогательный / частичный дамп HTML и тег <script> прямо в место, где он вызывается. Это кажется плохой идеей, поскольку означает, что элемент управления можно использовать только один раз на страницу.
  2. Есть два помощника. Один для вывода разметки HTML, а второй, который выплевывает JavaScript. Второй будет вызываться только один раз и вызываться снизу страницы, чтобы скрипт оказался в нужном месте. Если бы я изобрел второй элемент управления, похожий на этот, у меня было бы 4 помощника (2 для HTML, 2 для Javascript).
  3. Изобретите какой-нибудь ScriptManager, с помощью которого элементы управления могут регистрировать JavaScript. Менеджер сценариев будет иметь своего рода помощника, который будет добавлен в конец страницы и будет выгружать JavaScript для всех элементов управления, которые зарегистрировали некоторый фрагмент сценария. Вызов помощнику scriptmanager может быть в _layout.cshtml, чтобы он автоматически происходил на любой странице, которая в этом нуждается. Это ничего не даст, если страница не нужна. Думаю, это не очень похоже на MVC.
  4. Просто имейте помощника, который выплевывает HTML, а затем добавьте javascript в site.js, который включен на каждую страницу. Javascript был бы достаточно умен, чтобы ничего не делать, если бы не мог найти релевантную разметку на странице (в разметке был бы элемент-обертка с определенным классом). Однако при поиске разметки на всех страницах будут накладные расходы, включая страницы, на которых нет ни одного из этих элементов управления.
  5. То же, что и # 4, но поместите javascript в собственный файл .js и включайте его только на страницы, которые используют элемент управления. Это более эффективно для страниц, которые не используют элемент управления, но это дополнительный файл .js и связанный HTTP-запрос для страниц, которые его используют.

Я склоняюсь к # 4, но это решенная проблема? Есть ли лучший, 6-й вариант?

Ответы [ 2 ]

2 голосов
/ 27 ноября 2010

Моя компания использует переносимые области MVCContrib для упаковки кода в DLL для многократно используемых "компонентов"

Каждый из этих компонентов может быть вызван через метод расширения. Например:

Html.Components().ShowPoll();

Внутри каждого из этих компонентов есть способ зарегистрировать несколько файлов CSS / JS, которые являются встроенными ресурсами. Наш основной сайт будет извлекать файлы ресурсов и минимизировать + объединяет их перед обслуживанием.

Компонент также зарегистрирует любое событие на странице, которое будет вызываться во время события Document.OnReady в JQuery. Это позволяет каждому из компонентов быть мини-сайтами, автономными функциями с собственными маршрутами, моделями и представлениями.

По всему сайту обслуживается один и тот же JS-архив для всех компонентов. Один, потому что файл будет кеширован, а второй - устраняет сложность определения того, какие компоненты находятся на странице и какие ресурсы ей нужны.

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

0 голосов
/ 11 ноября 2011

Мне удалось решить эту проблему с помощью страницы макета, в которой был раздел с именем jsCode.

@RenderSection("jsCode",false)

Затем, когда мне это нужно, я создал на странице содержимого:

@section jsCode
{
<script type="text/JavaScript" src="myJsCode.js"></script>
}

youмог бы также создать помощника, который выплевывает скрипты, которые вам нужны для конкретной страницы, и инкапсулирует его таким образом, например:

 @helper MyJSFunction(string FunctionName){

        switch(FunctionName)
        {
            case "firstFN":
        <text>
    <script type="text/JavaScript">
        function SaySomethingSilly()
        {
            var sillySaying="We are the knights who say 'ni'!";
            alert(sillySaying);
        }
        </script>
        </text>

        break;
        case "secondFN":
        <text>
        <script type="text/JavaScript">
                function SaySomethingElse()
        {   var sillySaying="We are looking for a shrubbery...";
            alert(sillySaying);
        }   
        </script>
        </text>
    break;
    }
    }

Тогда моя страница контента (при условии, что мне нужны обе функции) выглядит следующим образом:

@{
Page.Title="Using helpers to create scripts";}
@section jsCode
{
@JSHelpers.MyJSFunction("firstFN")
@JSHelpers.MyJSFunction("secondFN")
}
<p>It works!</p>

, который выдает вывод:

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Using helpers to create scripts</title>


<script type="text/JavaScript">
    function SaySomethingSilly()
    {
        var sillySaying="We are the knights who say 'ni'!";
        alert(sillySaying);
    }
    </script>


    <script type="text/JavaScript">
            function SaySomethingElse()
    {   var sillySaying="We are looking for a shrubbery...";
        alert(sillySaying);
    }   
    </script>



    </head>
    <body>

<p>It works!</p>
    </body>
</html>

Теперь, если вы хотите получить супер-эффективность, (хотя на ум приходят другие слова), вы можете передать функции массив JSON илисловарь или даже строковый массив с именами сценариев, которые вы хотите использовать, или JavaScript для импорта, или что-то еще, и просто используйте один вызов помощника.Я думаю, что отдельные вызовы легче поддерживать, независимо от того, как вы загружаете возвращаемые значения вспомогательной функции, потому что вы можете сразу увидеть, какие сценарии вы используете на данной странице, и удалить или добавить один из них просто.-линейное изменение, а не изменение одного элемента массива.

Как всегда, ваш пробег может отличаться, но я без проблем выполнил пример на основе этого кода в WebMatrix Beta 2.

Лиза З. Морган http://www.lairhaven.com

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...