用任意内容封装可重用视图部分(即tile,portlet)的方法?

时间:2012-10-23 20:17:07

标签: asp.net-mvc asp.net-mvc-3

我仍然在使用MVC,并在一个使用大量“磁贴”的网站上工作(你知道,通常的“带有标准化标题的矩形部分和一些内容”模式)用于视觉显示。没有什么花哨的东西,只是一种将内容放入盒子以便于布局和导航的方法。目前,“瓷砖”(我的术语)是这样构建的:

<div class="tile">
    <div class="tile-header">
        <h2>Title</h2>
    </div>
    <div class="tile-body">
        (arbitrary content)
    </div>
</div>

注意:“任意内容”是指任何静态或动态内容,因此不一定能插入变量并传递给帮助者,我需要更多的灵活性。

我的问题是,用什么方法来封装这种模式并使代码调用变得更容易/更具表现力?我知道部分视图,但是如何将任意正文内容传递给局部视图? (这可能只是我对MVC显示的有限知识)

我尝试像这样构建Razor助手:

@Tile.Begin("Title")
    (arbitrary content)
@Tile.End()

但Razor窒息因为我不能包括“瓦片体”结束div。 (如果我这样做,那么我必须将正文内容作为字符串变量传递,这并不总是可行的)

我可以看到这样的事情:

@using (Tile.Begin("Title")) {
    (arbitrary content)
}

这对我来说似乎是最优雅的,虽然不像@Tile.Begin()和@Tile.End()调用那样容易扫描。根据我的理解,我将不得不创建一个类并实现IDisposable,但是当我尝试从帮助器类返回一串原始HTML标签时,它只是将编码的标签语法写入屏幕,所以我假设我遇到了同样的问题在这里?

感谢您的任何建议。 :)

1 个答案:

答案 0 :(得分:1)

好吧,我建议使用Display / EditorTemplates进行动态磁贴生成。你甚至可以将它们与一个html助手(不是剃刀助手)结合起来。

您使用自定义html帮助程序的问题是您没有正确执行此操作。您必须使用HtmlHelper对象。正确的方法是这样的:

public static class TileExtension {

    public static TileHelper Tile(this HtmlHelper helper, string title) {
        helper.ViewContext.Writer.Write(
            "<div class=\"tile\"><div class=\"tile-header\"><h2>" + title + "</h2></div>"
            + "<div class=\"tile-body\">"
        );
        return new TileHelper(helper);
    }

    private class TileHelper : IDisposable {
        private HtmlHelper _helper;
        public TileHelper(HtmlHelper helper) { _helper = helper; }
        public void Dispose() {
           _helper.ViewContext.Writer.Write("</div></div>");
        }
    }
}

然后你会像@using(Html.Tile("Title")) { // your content }

一样使用它

确保密切关注静态关键字,并在参数中使用this关键字。这些是扩展工作所必需的。

此外,您应该将您创建此类的命名空间添加到web.config的pages / namespaces元素中:

<pages>
    <namespaces>
        <add namespace="My.Name.Space" />
    </namespaces>
<pages>