Question

Il m'a été demandé de mettre à jour le menu sur un site Web, nous maintenons. Le site utilise le château Windors Monorail et NVelocity comme modèle. Le menu est rendu à l'aide des sous-classes sur mesure de ViewComponent, qui rendent les éléments li. À l'heure actuelle il n'y a qu'un seul niveau (horizontal), de sorte que le mécanisme actuel est très bien.

Il m'a été demandé d'ajouter des menus déroulants à certains des menus existants. Comme cela est la première fois que je l'ai vu et monorail NVelocity, je suis un peu perdu.

Ce qui existe actuellement:

<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>

Est-il possible d'avoir MenuComponents imbriquées (ou une nouvelle SubMenuComponent) quelque chose comme:

<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>

I nécessité de tirer le sous-menu (éléments ul et li) à l'intérieur de la méthode de rendu de substitution sur MenuComponent, donc l'utilisation des dérivés de ViewComponent imbriquées de travail peuvent pas. Je voudrais une méthode garder la méthode essentiellement déclarative pour créer des menus, si possible.

edit: je peux utiliser Context.RenderBody () pour rendre les derivitives de ViewComponent imbriquées, mais ils sont rendus avant d'être parent. Je suppose que le déchirants des sous-menus doivent être raccordés en quelque sorte dans la même sortie que le parent?

Était-ce utile?

La solution

Ma render originale méthode ressemblait

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());
}

Je avais besoin de connecter le 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>");    
}

Autres conseils

  

Je peux utiliser Context.RenderBody () pour rendre le imbriquée ViewComponent derivitives

dans votre méthode de rendu prioritaire, vous pouvez utiliser quelque chose comme

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

et peut-être utiliser RenderSection pourrait être utile de pouvoir passer outre certaines parties du modèle que vous utilisez le composant

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

il est également possible de modifier itterate et le contexte:

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

toutes ces solutions sont de fantaisie, mais je préfère generaly avoir un viewcomponent qui prend une viewmodel spécifique de but (dire HierarchicalMenuViewModel) en tant que paramètre et garder la logique simple de templating, il est plus facile à utiliser, et la personnalisation de sortie se produire

au moins pour les contrôles simples (qui parfois ne méritent une macro ou partielle en fonction du ViewEngine).

En fin de compte, les concepts viewcomponent illustré ci-dessus sont toujours agréable d'avoir quand faire un contrôle qui ont besoin d'une plus grande personnalisation. Un conseil est de prendre soin de documenter la logique de rendu ou de garder les choses simples (<= 10 lignes en méthode render)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top