This article is currently in the process of being translated into Chinese (~82% done).
Partial Views
到目前为止,我们只用了完整视图——在该视图中的所有东西都被一股脑地返回给了客户端。然而,有很多种可以将前端代码拆分放在不同位置的方法。这么做有很多好处,最显而易见的好处之一就是可以在许多地方复用视图代码的 与/或 逻辑。
我们将在本系列教程接下来的某个章节中谈到布局这个概念,利用布局,你就可以用一个通用模版包裹你的视图。不过,现在我们将对部分视图展开探讨。正如其名,部分视图允许你将视图拆分成多个文件。那么,对于你来说,为什么要那样做呢?
最最显而易见的理由就是——你可以提取视图的一部分,然后把这部分拆成一个部分视图,使你能够按预期那样,在其它的视图中使用这个特定的部分。例如,如果你的页面上有一个登录表单,你可以把它放到一个部分视图里。这样,你就可以随意将它插入到你想显示登录表单的位置,横跨多个页面。这样做也带来了额外的好处——通过把原本的视图拆分成规模更小的组件,其杂乱程度减小了。
现在,你就知道什么是部分视图了。下面就让我们来讨论一下,如何向你的项目中添加一个部分视图,然后在你的(完整)视图中使用它。
添加一个部分视图
ASP.NET MVC框架中的部分视图通常遵守这些约定:
- 部分视图被放在与当前使用它的(完整)视图相同的文件夹中。或者,当多个视图都在使用它的时候(这也是最常见的情况),它们应该被放在一个名为"Shared"的文件夹中,而Shared文件夹被放在Views文件夹中。
- 部分视图的文件名通常以一个下划线开头,单单用于区分该视图不是一个常规的,或者说完整的视图。
有了这些前导知识,现在就让我们添加部分视图吧。我们将它添加到 Shared文件夹中,以确保所有的视图都可以轻松访问它。
在对话框中,只要保证勾选了“创建为部分视图”这个选项就行了。
Visual Studio 现在将会刚给你创建一个新的空视图,你可以像在常规视图中那样,在部分视图中放入前端代码和Razor代码。例如,我在部分视图中添加了下列代码:
<div>Hello, world!</div>
<div>Today is @DateTime.Now.ToString()</div>
现在我们来尝试从某个(完整)视图中来引用它,我们就拿本系列教程前面讲创建常规视图的那篇文章时创建的视图为例。我们将使用MVC框架中,在Html帮助对象下能够找到的,一个名为PartialAsync()的方法:
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
@await Html.PartialAsync("_Greeting")
<span>More stuff here....</span>
现在先无需关注await关键字——加上该关键字是由于PartialAsync() 方法是异步的,不过这部分知识在本系列教程中就有点超纲了。
当你的视图被渲染时,部分视图中的内容就会被自动注入调用PartialAsync()方法的地方,将与当前视图剩下的部分一起混入进来。需要注意的是,我们不必指定部分视图的完整文件名和文件路径——因为视图发现(View Discovery)会自动搜索Shared文件夹中的视图。然而,如果你把部分视图放在一个完全不一样的位置,你就需要手动指定完整的相对路径,像下面这样:
@await Html.PartialAsync("/Views/SomeFolder/SomeSubFolder/_Greeting.cshtml")
向部分视图传递数据
由于部分视图本质上也就是一个常规的视图,如果你需要在部分视图中访问数据,方法也是一样的。你可以使用强类型模型(例如,与父级视图使用相同的模型),或者通过ViewDataDictionary实例传入自定义数据,甚至还可以组合使用这两者。由于这些功能对于视图和部分视图是相同的,我在这就不细说了。取而代之的是,我们要在本文中继续深究向视图中传递数据的课题。
我要向你展示一个炫酷的小例子,看看这一切是如何被PartialAsync()方法做到的。这个例子基于一个非常常见的场景——部分视图包含了一个对象的前端代码,而该对象需要在(完整)视图中被多次渲染。我们可以通过在循环中调用PartialAsync()方法对该对象进行多次渲染,我们也可以使用一个ViewDataDictionary实例来传递当前迭代的索引。
@for (int i = 0; i < 3; i++)
{
@await Html.PartialAsync("_Greeting", Model, new ViewDataDictionary(ViewData) { { "index", i } })
}
在部分视图中,你可以轻松访问自定义的数据:
<span>
Iteration number @ViewData["index"]
</span>
默认情况下,你可以在部分视图中直接访问父级视图的ViewData属性。然而,就像上述例子所描绘的那样,你当然可以自由地向部分视图中传入新的数据。
总结
部分视图使你能够将视图拆分为小“组件”,这些被拆分的“组件”可以在多个视图中进行复用。使用部分视图可以使原本的视图的混乱程度降低。