Asp.Net MVC中设计师友好的视图

时间:2009-10-29 21:38:11

标签: asp.net-mvc templates

我很享受Asp.Net MVC,我希望在即将到来的项目中使用它。然而,项目的一部分是强调能够将项目视图暴露给设计者以获取主题等内容。我期待的一个问题是Asp.Net MVC视图是以开发人员为中心的。我真的不想让设计师了解<%vs.<%=的内部情况,更不用说<%foreach ......

例如,采用典型的MVC菜单结构。

<div id="menu">
 <ul>
      <li><%= Html.ActionLink("Home", "Index", "Main")%></li>
      <li><%= Html.ActionLink("About", "About", "Main")%></li>
      <li><% Html.RenderPartial("LogOnUserControl"); %></li>
  </ul>
</div>

我更愿意告诉设计师使用像

这样的东西
<div id="menu">
 <ul>
      <li>{ActionLink "Home", "Index", "Main"}</li>
      <li>{ActionLink "About", "About", "Main"}</li>
      <li>{Partial "LogOnUserControl"}</li>
  </ul>
</div>

或者

<div id="menu">
 <ul>
      <li><my:ActionLink text="Home" action="Index" controller="Main" /></li>
      <li><my:ActionLink text="About" action="About" controller="Main" /></li>
      <li><my:Partial name="LogOnUserControl" /></li>
  </ul>
</div>

是的,最后看起来像一大堆UserControls。就个人而言,我不是真的使用UserControls来做这件事的粉丝只是因为这些控件的渲染几乎发生在其他所有事情之后(据我所知)并且我更喜欢更符合MVC生命周期的东西。我真正需要的是一组占位符以及用相关渲染替换它们的方法。

那么这里最好的地方是什么,我在这里看到了什么样的权衡。我可以想象出来的几个角度:

  • 我可以覆盖相关内容的自定义ViewPage类。也许是ViewPage.RenderView或ViewPage.FrameworkInitialize,但是你从那里得到的文字我不知道。
  • 创建一个自定义TextWriter并覆盖ViewPage.CreateHtmlTextWriter,然后我可以截取文本输出以替换内容。但是,这在周期中已经很晚了,如果我不小心的话,会混淆其他自定义过滤。
  • 创建我自己的IView和ViewEngine类。在想知道我是否会走向一个非常糟糕的地方之前,我没有走很远的路。
  • 可以模仿所需功能的自定义UserControl。

评论?其他选择?我自己的ViewEngine是我最好的选择吗?我自己的ViewPage?或者UserControl对象是否足够(请说不)?

4 个答案:

答案 0 :(得分:5)

看看Spark。它的语法类似于你的例子。

答案 1 :(得分:1)

正如Charles Conway所说,Spark肯定是要走的路。看一下例子。首先,在_ActionLink.spark中创建部分视图,代码为:

<viewdata text="String" action="String" controller="String">
${ Html.ActionLink(controller, action, text) }

然后你在其他视图中使用它:

<ActionLink text="Home" action="Index" controller="Main" />

您只需为设计师准备部分视图,然后以首选风格创建视图。这不容易吗?

修改

对不起,那是错的。 <ActionLink text="Home" action="Index" controller="Main" />将不起作用,因为Home,Index和Main被视为变量。按照你的意愿去做可能并不容易。

答案 2 :(得分:1)

我对当前项目有类似的要求,除了我的“设计师”或多或少的最终用户(知道他们的html方式的人,但这不是他们的工作)导致一些额外的挑战。我的实施可能过于具体,无法满足您的需求,但我会尽快解释,以免对其他人有用。

我想完全避免视图中任何类型的代码用于他们将要设计的页面,因此我决定使用模板系统来执行类似于第2点的操作,但不是在运行时。我也使用spark,虽然它不是为了用户的利益,因为它们不会触及任何看似代码的东西。

基本上,用户创建一个完整的仅HTML模板,该模板具有用户控件和部分视图的占位符标记。然后,用户通过解析它的界面上传模板并将其转换为spark视图。

例如。 对于图片库,<gallery />会被解析为!{Html.Gallery(Model)}<use file="Gallery"/>。对于描述字段,<desc name="Kitchen" />被解析为!{Html.Description(Model, x => x.Descriptions.Kitchen)}。它还检查“Kitchen”实际上是正在模板化的对象/页面的属性,或者为库中传入的模型实际上包含一组图像以避免运行时错误。

可以在标记中指定其他属性,以将其他参数传递给已解析的控件。如果指定的控件需要Javascript,那么它也包含在视图中。如果解析有任何问题,则返回输出,指定哪个占位符无效以及原因。

答案 3 :(得分:0)

虽然回答并接受了,但我没有看到这样的例子:你为什么不使用:

<li><a href='<%= Url.Action("Home", "Index")%>'>Main</a></li&GT;

类似于Spark。我更喜欢Html.ActionLink,Html.BeginForm等,只要有可能(几乎总是除了表单控件之外,使用Html助手更容易进行自动名称编码)。

您的设计师链接。