动态编辑器使用模型中的模板

时间:2012-10-01 11:58:53

标签: c# asp.net-mvc asp.net-mvc-3 templates razor

该项目目前是MVC3,但如果需要可以升级。

我试图让内容编辑器改进简单的cms。目前我们使用

@Html.EditorFor(model=>model.Content) //Content is a List<EditableContent>

EditableContent具有字符串EditorView的(全新)属性。我们的想法是为特定的内容项命名合适的编辑器。

如果EditorView为null,我想要使用我的默认EditableContent模板,否则使用EditorView作为命名模板。我知道编辑器的重载需要一个模板,但是对于每个内容项都会使用相同的模板,但这不是我想要的。

我确实尝试使用我的默认模板并且基本上正在执行

//Shared/EditorTemplates/EditableContent.cshtml
@model Website.Areas.Admin.EditableContent

@if (!string.IsNullOrWhiteSpace(Model.EditorView))
{
<text>
    @Model.EditorView
    @Html.EditorForModel(Model.EditorView)
</text>
}
else
{
  //Original template
}

奇怪的是,在这种情况下,视图位于(我有一个稍微自定义的视图引擎,似乎正确定位视图)。视图的名称(通过@ Model.EditorView)被发送到页面,但@ Html.EditorForModel()不会产生任何内容。

如何使用EditorFor或类似方法为每个项目使用自定义模板?

2 个答案:

答案 0 :(得分:2)

接口

interface IEditableContent
{
    public virtual DatabaseContext.Content Content { get; set; }
}

实施

class SomeTypeEditableContent : IEditableContent
{
    public SomeTypeEditableContent(DatabaseContext.Content c)
    {
        Content = c;
    }
}

服务(存储库或控制器操作)

List<IEditableContent> lEditableContent = new List<IEditableContent>();
foreach(var c in db.Contents)
{
    switch (c.EditorView)
    {
    case "SomeType":
        lEditableContent.Add(new SomeTypeEditableContent(c));
        break;
    default:
        lEditableContent.Add(new DefaultEditableContent(c));
        break;
    }
}

查看

@Html.EditorFor(model=>model.ListContent) //List<IEditableContent>

可编辑的某种类型模板

@model SomeTypeEditableContent
//Display this as a editable string

默认可编辑内容模板

@model IEditableContent
//Use default display

对不起,我没有时间去测试它。让我知道它是怎么回事,如果没有,我会编辑/删除这个答案。我会发布这个作为评论,但我需要anotation和格式化。但至少它可以让你了解我的想法。

- 编辑 -

这个例子的目的是向您展示MVC框架应该能够为实现的接口确定正确的模板,即使只是简单地提供类型为接口的对象。它将使用refelction(我相信?)来找到最高级别的定义,然后寻找模板。

-Edit 2(基于评论) -

更改了例子以匹配新规范

答案 1 :(得分:1)

您尝试从已覆盖模板的视图中覆盖编辑器模板,这似乎很奇怪。我不确定这是否有效(可能,但我从未尝试过,所以我不知道)。我已经在上面的问题中添加了几条评论。

如果事实证明尝试从EditorTemplates文件夹中指定模板不起作用,这是可以理解的,我认为您可以通过引入自定义EditorForModel()覆盖来实现您想要的效果。您可以使用David Ebbo的Razor Generator VS扩展来定义可在整个项目中使用的剃刀助手。

/// /Views/Helpers/AndiEditorForExtensions.cshtml
@helper AndiEditorFor(HtmlHelper html, Website.Areas.Admin.EditableContent model) {
    if (!string.IsNullOrWhiteSpace(Model.EditorView)) {
    <text>
        @Model.EditorView
        @Html.EditorForModel(Model.EditorView)
    </text>
    }
    else {
        // Call @Html.EditorFor(), which will use the default editor template (i.e., NOT your custom one defined in the database)
        @Html.EditorFor(model) 
    }
}

然后从您从数据库加载EditableContent项目并显示它们的普通代码中,调用您的自定义扩展程序:

@Html.AndiEditorFor(model)

UPDATE:

更好的选择可能是完全跳过Razor Generator。只需定义一个自定义的HtmlHelper,模仿EditorExtensions methods即可。添加一个类似的if / else来处理具有值的Model.EditorView。