Как создать вложенные ViewComponents в Monorail и NVelocity? - PullRequest
0 голосов
/ 06 мая 2010

Меня попросили обновить меню на веб-сайте, который мы поддерживаем.Сайт использует Castle Windors Monorail и NVelocity в качестве шаблона.В настоящее время меню отображается с использованием пользовательских подклассов ViewComponent, которые отображают элементы li.На данный момент существует только один (горизонтальный) уровень, поэтому с текущим механизмом все в порядке.

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

То, что в настоящее время существует:

<ul>
    #component(MenuComponent with "title=Home" "hover=autoselect" "link=/")
    #component(MenuComponent with "title=Videos" "hover=autoselect")
    #component(MenuComponent with "title=VPS" "hover=autoselect" "link=/vps")                                   
    #component(MenuComponent with "title=Add-Ons" "hover=autoselect" "link=/addons")                    
    #component(MenuComponent with "title=Hosting" "hover=autoselect" "link=/hosting")                           
    #component(MenuComponent with "title=Support" "hover=autoselect" "link=/support")                           
    #component(MenuComponent with "title=News" "hover=autoselect" "link=/news")
    #component(MenuComponent with "title=Contact Us" "hover=autoselect" "link=/contact-us") 
</ul>

Возможно ли иметь вложенные компоненты меню (или новыйSubMenuComponent) что-то вроде:

<ul>
    #component(MenuComponent with "title=Home" "hover=autoselect" "link=/")
    #component(MenuComponent with "title=Videos" "hover=autoselect")
    #blockcomponent(MenuComponent with "title=VPS" "hover=autoselect" "link=/vps")                                  
        #component(SubMenuComponent with "title="Plans" "hover=autoselect" "link=/vps/plans")
        #component(SubMenuComponent with "title="Operating Systems" "hover=autoselect" "link=/vps/os")
        #component(SubMenuComponent with "title="Supported Applications" "hover=autoselect" "link=/vps/apps")
    #end
    #component(MenuComponent with "title=Add-Ons" "hover=autoselect" "link=/addons")                    
    #component(MenuComponent with "title=Hosting" "hover=autoselect" "link=/hosting")                           
    #component(MenuComponent with "title=Support" "hover=autoselect" "link=/support")                           
    #component(MenuComponent with "title=News" "hover=autoselect" "link=/news")
    #component(MenuComponent with "title=Contact Us" "hover=autoselect" "link=/contact-us") 
</ul>

Мне нужно нарисовать подменю (элементы ul и li) внутри переопределенного метода Render в MenuComponent, поэтому использование вложенных производных ViewComponent может не работать.Я хотел бы, чтобы метод оставался в основном декларативным методом для создания меню, если это вообще возможно.

edit: я могу использовать Context.RenderBody () для рендеринга вложенных производных ViewComponent, но они выводятся дородитель.Я предполагаю, что разметка подменю должна каким-то образом подключаться к тому же выводу, что и родительский?

Ответы [ 2 ]

0 голосов
/ 21 июня 2010

Я могу использовать Context.RenderBody () для рендеринга вложенных производных ViewComponent

в переопределении метода Render вы можете использовать что-то вроде

RenderView("header");
RenderBody();
RenderView("footer");

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

if(HasSection("header")){
    RenderSection("header");
} else {
    RenderView("header");
}

также возможно итерировать и изменять контекст:

for(var item in this.SubItems){
    PropertyBag["item"] = item;
    if(HasSection("item")){
        RenderSection("item");
    } else {
        RenderView("item");
    }
}

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

по крайней мере для простых элементов управления (которые в некоторых случаях заслуживают только макроса или частичного в зависимости от viewengine).

В конце концов, представленные выше концепции viewcomponent все еще хороши, когда вы выполняете управление, требующее дополнительной настройки. Совет заключается в том, чтобы позаботиться о документировании логики рендеринга или о ее простоте (<= 10 строк в методе рендеринга) </p>

0 голосов
/ 06 мая 2010

Мой оригинальный метод рендеринга выглядел как

public override void Render()
{
    var buffer = new StringBuilder();           
    var extraClass = _hoverState == MenuHoverState.Selected ? "class=\"Selected\"" : "";

    // Menu Item Start
    buffer.Append("<li><a href=\"" + ComponentParams["link"] + "\"" + extraClass + ">");

    // Menu Text
    buffer.Append(ComponentParams["title"]);

    // Menu Item End
    buffer.Append("</a></li>");                     
    RenderText(buffer.ToString());
}

Мне нужно было подключиться к Context.Writer:

public override void Render()
{
    var buffer = new StringBuilder();           
    var extraClass = _hoverState == MenuHoverState.Selected ? "class=\"Selected\"" : "";

    // Menu Item Start
    buffer.Append("<li><a href=\"" + ComponentParams["link"] + "\"" + extraClass + ">");

    // Menu Text
    buffer.Append(ComponentParams["title"]);

    // Menu Item End
    buffer.Append("</a><ul class=\"subMenu\" style=\"display:none;\">");                        
    Context.Writer(buffer.ToString());
    Context.RenderBody(Context.Writer);
    Contet.Writer("</ul></li>");    
}
...