ASP.NET MVC HtmlHelper расширения для элементов управления YUI (пользовательские интерфейсы Yahoo)? - PullRequest
4 голосов
/ 26 января 2009

Кто-нибудь написал классы HTMLHelper для MVC, которые помогают с библиотекой пользовательского интерфейса Yahoo ?

Например, я написал вспомогательный метод для преобразования «модели меню» в HTML-разметку, необходимую для поддержки управления меню Yahoo . Шаблон MVC здесь хорошо работает, потому что, очевидно, если я решу переключиться на другую реализацию меню, я могу просто написать нового помощника и не трогать модель.

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

Сначала нам понадобится простая структура данных для самой модели меню. Вы добавили бы это к своей модели страницы с обычными соглашениями MVC. Например, я получаю доступ к списку пунктов меню из моего представления через ViewData.Model.MainMenu.MenuOptions.

public class MenuItem

{
    public string Text { get; set; }
    public string Description { get; set; }
    public string RouteURL { get; set; }
    public bool SeparatorBefore { get; set; }

    public List<MenuItem> MenuItems { get; set; }
}

Метод расширения. Введите пространство имен, доступное для вашего просмотра.

public static class YUIExtensions
    {
        public static string RenderMenu(this HtmlHelper html, string id, List<MenuItem> menuItems)
        {
            // <div id="mnuTopNav" class="yuimenubar yuimenubarnav">
            //    <div class="bd">
            //        <ul class="first-of-type">

            //            <li class="yuimenubaritem first-of-type"><a class="yuimenubaritemlabel" href="#store">Store</a></li>

            //            <li class="yuimenubaritem"><a class="yuimenubaritemlabel" href="#products">Products</a>

            //                <div id="communication" class="yuimenu">
            //                    <div class="bd">
            //                        <ul>
            //                            <li class="yuimenuitem"><a class="yuimenuitemlabel" href="http://360.yahoo.com">360&#176;</a></li>
            //                            <li class="yuimenuitem"><a class="yuimenuitemlabel" href="http://mobile.yahoo.com">Mobile</a></li>
            //                            <li class="yuimenuitem"><a class="yuimenuitemlabel" href="http://www.flickr.com">Flickr Photo Sharing</a></li>
            //                        </ul>
            //                    </div>
            //                </div>     
            //            </li>

            //        </ul>            
            //    </div>
            //</div>   

            int menuId = 0;
            HtmlGenericControl menuControl = CreateControl(html, id, 0, ref menuId, menuItems);

            // render to string
            StringWriter sw = new StringWriter();
            HtmlTextWriter tw = new HtmlTextWriter(sw);
            tw.Indent = 1;
            menuControl.RenderControl(tw);
            return sw.ToString();
        }

        private static HtmlGenericControl CreateControl(HtmlHelper html, string id, int level, ref int menuId, List<MenuItem> currentItems)
        {
            var menu = new HtmlGenericControl("div");
            menu.Attributes["class"] = (level == 0) ? "yuimenubar yuimenubarnav" : "yuimenu";
            menu.Attributes["id"] = id;

            var div_bd = new HtmlGenericControl("div");
            menu.Controls.Add(div_bd);
            div_bd.Attributes["class"] = "bd";

            HtmlGenericControl ul = null;

            int i = 0;
            foreach (var menuItem in currentItems)
            {
                if (ul == null || menuItem.SeparatorBefore)
                {
                    ul = new HtmlGenericControl("ul");
                    div_bd.Controls.Add(ul);

                    if (i == 0)
                    {
                        ul.Attributes["class"] = "first-of-type";
                    }
                }

                var menuItem_li = new HtmlGenericControl("li");
                menuItem_li.Attributes["class"] = (level == 0) ? "yuimenubaritem" : "yuimenuitem";
                if (i == 0)
                {
                    menuItem_li.Attributes["class"] += " first-of-type";
                }
                ul.Controls.Add(menuItem_li);

                var href = new HtmlGenericControl("a");
                href.Attributes["class"] = (level == 0) ? "yuimenubaritemlabel" : "yuimenuitemlabel";
                href.Attributes["href"] = menuItem.RouteURL;
                href.InnerHtml = menuItem.Text;
                menuItem_li.Controls.Add(href);

                if (menuItem.MenuItems != null && menuItem.MenuItems.Count > 0)
                {
                    menuItem_li.Controls.Add(CreateControl(html, id + "_" + (menuId++), level + 1, ref menuId, menuItem.MenuItems));
                }
                i++;
            }

            return menu;
        }
    }

Прикрепите этот код, где вы хотите создать меню в вашем представлении (у меня это на главной странице):

<%= Html.RenderMenu("mnuTopNav", ViewData.Model.MainMenu.MenuOptions) %>

Если вы ленивый или не знаете о YUI, вам это тоже понадобится в вашем <HEAD>

<!-- Combo-handled YUI CSS files: -->
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.6.0/build/menu/assets/skins/sam/menu.css">
<!-- Combo-handled YUI JS files: -->
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/container/container_core-min.js&2.6.0/build/menu/menu-min.js"></script>

В настоящее время генерируется разметка для верхней навигационной панели в стиле nav , но ее можно легко изменить.

Я надеялся, что кто-то другой делал то же самое для некоторых других элементов управления.

Похоже, хороший кандидат на проект с открытым исходным кодом - но у меня нет времени, чтобы начать это.

Рекомендации по внедрению приветствуются!

Ответы [ 2 ]

3 голосов
/ 05 февраля 2009

Прошлой ночью я немного подумал об этом, и мне стало интересно, есть ли еще возможность здесь сделать HTMLHelpers общего назначения, используя YUI или любые другие виджеты Javascript / HTML, которые вы хотите.

Например, если был интерфейс для IMenu и один для ITextBox, ICheckBox, IRichTextEditor, ICarousel и т. Д., Очень похожий на ваш класс для MenuItem, то вы могли бы иметь реализацию YUI каждого из этих интерфейсов, по одному для JQuery. один для MooTools или один для простого HTML / CSS.

Часть того, что спровоцировало это, является обобщением, которое статьи как это: http://designingwebinterfaces.com/essential_controls переходят к элементам управления пользовательского интерфейса в Интернете для богатых веб-приложений.

Эти интерфейсы будут содержать все основные элементы, которые очевидны на первый взгляд: идентификатор, имя, значение, список, стиль, OnChange, OnClick и т. Д., А также менее очевидные элементы, такие как ValidationRegex, HelpText и т. Д.

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

Вам придется иметь дело с тем, что должно произойти, если вы дадите что-то вроде ValidationRegex для базовой реализации HTML, и у вас не будет способа с этим справиться, но я думаю, что этот путь стоит обдумать. Я также думаю, что было бы более разумно реализовать это отдельно от существующего пространства имен HTMLHelper, унаследовав его или просто переопределив его, но я часто ошибаюсь на этом раннем этапе разработки решения.

Материал YUIAsp.NET интересен, но больше ориентирован на WebForms и пользовательские элементы управления, чем на направление, которое ASP.NET MVC, и даже более того, на Fubu MVC в последнее время.

Я немного возился с этой идеей и действительно заинтригован возможностями.

2 голосов
/ 26 января 2009

Simon

Я не уверен, что это полезно в отношении вопроса MVC, но есть хороший проект с открытым исходным кодом, целью которого является упрощение работы с YUI в .NET:

http://www.yuiasp.net/

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

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

-Эрик

...