UI 辅助方法模板化支持

Html.EditorFor() 和 Html.DisplayFor() 辅助方法对显示标准的数据类型以及含有多个属性的复杂对象有内置的支持。就象上面说的,它们还支持通过在视图模型上施加象[DisplayName]和 [ScaffoldColumn]特性这样的基本的定制机制。

但经常地,开发人员想要能够进一步定制UI辅助方法的输出,对生成的东西要有完全的控制。Html.EditorFor() 和 Html.DisplayFor()辅助方法通过一个模板化机制支持这个要求,这个机制允许你定义外部的模板,替换原先的,完全控制显示的输出。更棒的 是,你还可以在每个数据类型/类的基础上定制要显示的内容。

在第一个预览版中,你可以在\Views\[控制器名称]目录下(如果你想要定制某个特定的控制器所用视图的显示的话)或在\Views \Shared目录下(如果你想要定制一个应用中所有视图和控制器的显示的话)加一个“EditorTemplates” 或者 “DisplayTemplates” 子目录。

然后你可以往这些目录中加分模板(partial template)文件,针对个别数据类型或者类来定制显示输出。例如,在下面,我在\Views\Shared目录下加了一个EditorTemplates子目录,在其中加了三个定制的模板文件:

  

上面的“Customer.ascx”模板表示我想要定制在调用Html.EditorFor()时其参数为Customer对象时的输出(例如, 我可以定制Customer属性的精确顺序和布局)。上面的“DateTime.ascx” 模板表示我想要定制在调用Html.EditorFor()时其参数为DateTime属性时的输出(例如,我也许想要使用JavaScript的日历控 件,而不是普通的文本框)。我也可以在目录中加一个“Object.ascx” 模板,如果我想要替代所有对象的默认显示的。

除了在每个类的基础上定制输出外,你还可以在目录中加“具名模板(named templates)”。一个常见的场景也许是 “CountryDropDown”模板,它处理字符串数据类型,但不是提供标准的文本框,而是显示一个用户可以选择的列出了国家名称值的< select>下拉框。下面是这个编辑器模板的一个例子:

 

然后,我们可以在调用Html.EditorFor()辅助方法时,把上面这个模板的名称作为参数传给它,明确地表示我们想要使用这个模板。例如,在下面,除了指定Country属性的lambda表达式外,我们还指定了在显示时要使用的编辑器模板的名称

  

或者,你也可以在你的ViewModel属性和类型上指定“UIHint”特性。这允许你在单一一个地方指定要使用的默认编辑器或者显示器模板,然后在整个应用的所有视图中使用指定的模板(而不必显式地将这个名称作为参数传给Html.EditorFor)。

下面是一个如何使用UIHint特性来表示Customer.Country属性(字符串类型)应该在默认情形下显示时使用CountryDropDown模板的例子:

  

一旦在我们的视图模型上设置上述特性后,在使用Html.EditorFor()显示那个属性时,我们就不再需要显式指定模板名称了。现在,在 /Customers/Create URL上点击刷新时,我们的Country属性就会显示为一个下拉框,而不是一个标准的文本框: