2010-05-05 3 views
0

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

Мне было предложено добавить выпадающие меню в некоторые из существующих меню. Поскольку это первый раз, когда я видел Monorail и 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> 

Можно ли иметь вложенные MenuComponents (или новый 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> 

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

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

ответ

0

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

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>");  
} 
0

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

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

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

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

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

также можно itterate и изменить контекст:

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

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

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

В конце концов, концепции видкомпонента, проиллюстрированные выше, по-прежнему приятно иметь при управлении, которые нуждаются в дополнительной настройке. Совет должен заботиться о документировании логики рендеринга или его простоте (< = 10 строк в режиме рендеринга)