Попытка добавить JS и CSS в файл макета на веб-сайте MVC 3 Razor из частичных представлений - PullRequest
7 голосов
/ 15 марта 2011

В настоящее время я использую метод, похожий на следующий код, чтобы добавить файлы сценариев и CSS в начало файла макета.

public static class HtmlHelperExtensions
{
    public static MyCompanyHtmlHelpers MyCompany(this HtmlHelper htmlHelper)
    {
        return MyCompanyHtmlHelpers.GetInstance(htmlHelper);
    }    
}

public class MyCompanyHtmlHelpers
{
    private static MyCompanyHtmlHelpers _instance;

    public static MyCompanyHtmlHelpers GetInstance(HtmlHelper htmlHelper)
    {
        if (_instance == null)
            _instance = new MyCompanyHtmlHelpers();

        _instance.SetHtmlHelper(htmlHelper);

        return _instance;
    }

    private HtmlHelper _htmlHelper;

    public ItemRegistrar Styles { get; private set; }
    public ItemRegistrar Scripts { get; private set; }

    public MyCompanyHtmlHelpers()
    {
        Styles = new ItemRegistrar(ItemRegistrarFromatters.StyleFormat);
        Scripts = new ItemRegistrar(ItemRegistrarFromatters.ScriptFormat);
    }

    private void SetHtmlHelper(HtmlHelper htmlHelper)
    {
        _htmlHelper = htmlHelper;
    }
}

public class ItemRegistrar
{
    private readonly string _format;
    private readonly List<string> _items;

    public ItemRegistrar(string format)
    {
        _format = format;
        _items = new List<string>();
    }

    public ItemRegistrar Add(string url)
    {
        if (!_items.Contains(url))
            _items.Insert(0, url);

        return this;
    }

    public IHtmlString Render()
    {
        var sb = new StringBuilder();

        foreach (var item in _items)
        {
            var fmt = string.Format(_format, item);
            sb.AppendLine(fmt);
        }

        return new HtmlString(sb.ToString());
    }
}

public class ItemRegistrarFromatters
{
    public const string StyleFormat = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
    public const string ScriptFormat = "<script src=\"{0}\" type=\"text/javascript\"></script>";
}

Использование Html.MyCompany().Styles.Add("/Dashboard/Content/Dashboard.css"); для добавления файлов ... И @Html.MyCompany().Styles.Render() для их рендеринга в Layout_.cshtml.

Моя проблема в том, что это статический метод, означающий, что он сохраняет список таблиц стилей и файлов сценариев.

Мне нужно сделать то же самое, что и это, но без сохранения настойчивости.

Мне нужно, чтобы списки переделывались при каждом запросе, так как они меняются от страницы к странице, как выглядит эта конкретная страница.

Можно ли очистить списки при каждом запросе до добавления необходимых сценариев или, возможно, после их вывода?

Обновление: Причина, по которой не используется раздел RenderPartial или RenderaActions, заключается в том, что одна и та же таблица стилей или файл сценария могут быть добавлены в файл макета несколько раз.

Сайт im building имеет Layout_.cshtml с базовым макетом. Это, в свою очередь, используется представлением, которое перебирает список элементов, и для каждого элемента вызывается RenderAction, который выводит конкретное частичное представление для этого элемента. Эти частичные представления иногда требуют добавления таблиц стилей и сценариев.

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

Обновление 2: Реальный вопрос заключается в том, как выполнить функцию такого же типа (глобальный список), но без использования статического метода Extension.

Ответы [ 4 ]

9 голосов
/ 15 марта 2011

Я бы сделал это с разделами, т. Е.

@section head {
    ...add whatever you want here...
}

И визуализировал бы раздел "head" из макета:

<head>
...other stuff here...
@RenderSection("head", required: false)
</head>

Если вам не нужны разделы, ине хочу передавать его, я бы использовал здесь HttpContext;сохранить некоторые данные против HttpContext.Current.Items[someKey].Если он нулевой, создайте новый и сохраните его в контексте.

Например:

public static MyCompanyHtmlHelpers GetInstance(HtmlHelper htmlHelper)
{
    const string key = "MyCompanyHtmlHelpersInstance";
    IDictionary items = (htmlHelper == null || htmlHelper.ViewContext == null
        || htmlHelper.ViewContext.HttpContext == null)
        ? HttpContext.Current.Items : htmlHelper.ViewContext.HttpContext.Items;

    MyCompanyHtmlHelpers obj = (MyCompanyHtmlHelpers)items[key];
    if (obj == null)
    {
        items.Add(key, obj = new MyCompanyHtmlHelpers());
    }
    return obj;
}
1 голос
/ 13 июля 2011

Я сам столкнулся с той же проблемой и что-то придумал, надеюсь, это поможет.

Посмотрите этот другой вопрос, из того, что я придумал:

Как отобразить JavaScript в раздел MasterLayout из частичного представления?

0 голосов
/ 08 сентября 2011

попробуйте

Добавление файлов CSS или JavaScript в макет головы из представлений или частичных представлений

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

Для частичных представлений передайте данные в статический класс.

0 голосов
/ 15 марта 2011

Что вам нужно сделать, так это немного расширить хелпер Html.

public static MvcHtmlString AddStyle(this HtmlHelper<TModel> html, string styleUrl)
{
    string styleTag = string.Format("<link rel='stylesheet' type='text/css' href='{0}' />", styleUrl);
    return MvcHtmlString.Create(styleTag);
}

Тогда, на ваш взгляд, просто выполните:

<head>
    @Html.AddStyle("/Dashboard/Content/Dashboard.css")
</head>

Если вам нужны относительные корневые URL, просто бросьтев помощнике по содержанию URL.

<head>
    @Html.AddStyle(Url.Content("~/Dashboard/Content/Dashboard.css"))
</head>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...