分享

ASP.NET MVC3:通过Razor实现布局

 A_POST 2014-08-07

通过Razor使用布局

在我上一篇博客中,我演示了一个简单的例子来呈示一列商品目录的商品URL:

下面用一个简单的ProductsController实现上面的商品URL列表。它从数据库返回一列商品种类,然后传到视图文件,以在浏览器以合适的HTML响应呈示出来。

下面显示Index.cshtml视图文件(用Razor来实现的)

上面的视图文件没有使用布局页面——这意味着我们往站点添加新的URLs和页面的时候我们会在不同的地方重复我们的核心网站布局。使用布局可以让我们避免这种重复,以后管理我们的网站设计更加容易。让我们现在更新我们的示例来使用一个吧。

重构以使用布局

Razor使重构现有页面以使用布局变得简单。 让我们用上面的简单示例做一下吧。 我们的第一步是往项目的\视图\共享文件夹(这是通用视图文件、模板所放置的地方)下添加一个“SiteLayout.cshtml”文件:

SiteLayout.cshtml

我们将用SiteLayout.cshtml文件来定义我们网站的通用内容, 可能看起来像下面这样:

上面文件需要注意:

·        文件顶端不需要有一个@inherits指令了。你想要的话也可以选择加上一个(比如:如果你希望有一个定制基类),但是这不是必需的。这样就能让文件美观而干净, 而且也方便程序员之外的人处理文件, 遇到他们不理解的概念也不会觉得疑惑。

·        我们在上面的布局文件中调用@RenderBody()方法,

·        我们在<head>部分的<title>元素内输出“View.Title”属性。我还将讨论一下这是怎么使用的。

现在我们有了一个通用的布局模板来保持我们网站任意页面的外观一致性。

Index.cshtml

我们下面根据我们刚才创建的SiteLayout.cshtml文件来更新我们的Index.cshtml视图。下面是它可能的样子的首次截图:

关于上面的文件需要注意:

·        我们不需要将我们的主体内容包装在一个标记或元素中——Razor将默认自动将Index.cshtml中的内容视为布局页面的主体部分。如果我们的布局有几个可更换的区域,我们能选择性地定义“name sections”。但是Razor让90%的情况(你只需要有一个主体部分就可以了)超级干净而简练。

·        上面我们编程设置了Index.cshtml页面中的View.Title的值。我们的Index.cshtml文件中的代码会比SiteLayout.cshtml中的代码先执行——这样我们就能编写视图代码编程设置需要被呈示到布局的值。对像设置页面的标题,和为搜索引擎优化内的<head>设置<meta>元素这样的事情,上面功能尤其有用。

·        刚才我们在Index.cshtml页面内编程设置所用的布局模板。它也可以通过设置视图上的布局属性来实现(注意:在第一个预览版中,这个属性被称为“LayoutPage”——我们在ASP.NET MVC 3 Beta版中将其更名为“Layout”)。我将简单地介绍设置这个属性的几个替代方法。

现在当我们在网站内请求/商品URL的时候,将得到返回如下HTML:

注意上面是怎样返回一个SiteLayout.cshtml和Index.cshtml的合并HTML内容的。顶端的“Product categories”标题根据视图正确设置,我们的动态目录列表显示在正确的位置。

用ViewStart保持事物“干燥”(DRY)

现在我们在Index.cshtml文件的顶端通过编程设置所要用的布局文件。对包含一些专门针对视图的逻辑的情况还好,因为布局文件会随着特定视图的不同而不同。但是这样设置的话会最终导致大部分网页应用程序的冗余和重复——要不就所有的视图都使用同样的布局,要不这样:如果他们有不同的布局(比如:对移动设备或本地化网站),选择使用布局的逻辑在所有视图中通用。

好消息是Razor包括一个能让我们不需要在每个视图中显式设置布局的新功能——而是让我们能一次性定义网站内所有视图的布局逻辑,从而让我们的视图文件更干净,也更容易维护(确保我们坚持DRY原则:不要重复你自己):

自ASP.NET MVC 3 BETA发布版开始, 你现在能在项目的\视图文件夹下添加一个_ViewStart.cshtml(或VB的_ViewStart.vbhtml)的文件:

_ViewStart文件可以被用来定义想要在每次视图呈现开始的时候执行的通用视图代码。比如,我们能在在我们的_ViewStart.cshtml文件中写下面这样的代码来编程设置每个视图的默认布局属性为SiteLayout.cshtml文件:

因为这段代码在每个视图开始的时候执行,我们不需要在任何单个视图文件中显式设置布局(除非我们想要覆盖上面的默认值)。

重要: 因为_ViewStart.cshtml允许我们编写代码,所以我们能有选择地让我们的布局选择逻辑比基本的属性设置更丰富。比如:我们能根据访问网站的设备的不同来使用不同的布局模板——有针对手机或tablet等这些设备的优化布局,针对PCs/笔记本的桌面优化布局。或者如果我们创建一个被不同的用户使用的CMS系统或通用共享应用,我们能根据访问网站的客户(或角色)的不同而选择不同的布局。

这大大提高了用户界面的灵活用。允许你更容易地一次性编写视图逻辑,避免在不同的地方重复它。

注意:你也能在一个控制器或操作筛选器重指定布局。这样如果你更愿意保留布局逻辑在那里,你也能那样做。

完成的示例

下面是我们一直在创建的简单应用程序的截图:

下面是ProductsControlles,它实现/Product URL并从数据库返回目录并将它们传到视图模板呈示出来:

这里是我们用来呈示/Products响应的Index.cshtml视图:

这里是用来在网站内实现统一外观的SiteLayout.cshtml布局文件:

这里是指定我们所有视图都默认使用SiteLayout.cshtml文件的_ViewStart.cshtml文件:

这里是/Products URL所生成的HTML:

既然我们现在的网站上有了一个通用布局文件,我们能在应用程序中构建更多功能,控制器和视图——从而获得一个连贯又容易维护的网站用户界面体验。

更多高级内容

人们经常问两个常见问题:

1) 我能使用嵌套的布局文件吗?

2) 在一个布局文件中,我们有多个非连续的可替换区域吗?——这样我就能在几处不同的地方填充我自己的视图文件。

这两个问题的答案都是肯定的!我以后会写一些展示如何实现的示例的博文。

总结

像我之前提到的,我们发布ASP.NET MVC 3和Razor所坚持的一个主旨是让你写的代码更干净更简洁。我们认为这个发布版带来的新布局功能非常有助于方便视图文件的读写。

希望对您有所帮助。

Scott


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多