代码之家  ›  专栏  ›  技术社区  ›  Rob Gray

如何在Monorail和NVelocity中创建嵌套的ViewComponents?

  •  0
  • Rob Gray  · 技术社区  · 14 年前

    我被要求更新我们网站上的菜单。该网站使用Castle Windors Monorail和NVelocity作为模板。菜单当前使用ViewComponent的自定义子类呈现,这些子类呈现li元素。目前只有一个(水平)水平,所以目前的机制是好的。

    <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(或新的submenucomponents),例如:

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

    我需要在MenuComponent上重写的Render方法中绘制子菜单(ul和li元素),因此使用嵌套的ViewComponent派生可能不起作用。如果可能的话,我希望有一个方法保留创建菜单的基本声明性方法。

    编辑:我可以使用Context.RenderBody()来呈现嵌套的ViewComponent派生对象,但它们是在父级之前呈现的。我猜子菜单的呈现需要以某种方式连接到与父菜单相同的输出中?

    2 回复  |  直到 14 年前
        1
  •  0
  •   Rob Gray    14 年前

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

    我需要融入上下文。作者:

    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>");    
    }
    
        2
  •  0
  •   smoothdeveloper    14 年前

    我可以使用Context.RenderBody()来呈现嵌套的ViewComponent派生

    在渲染方法覆盖中,可以使用

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

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

    至少对于简单控件(有时只需要一个宏或部分宏,具体取决于viewengine)。

    最后,当执行需要更多定制的控件时,上面说明的viewcomponent概念仍然很好。建议注意记录呈现逻辑或保持其简单(<=渲染方法中的10行)

    推荐文章