繁体   English   中英

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

[英]Dynamic EditorFor using template from Model

该项目当前为MVC3,但可以根据需要进行升级。

我正在尝试为简单的cms改进内容编辑器。 目前我们使用

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

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

我想做的是,如果EditorView为null,请使用默认的EditableContent模板,否则,请使用EditorView作为命名模板。 我知道带有模板的EditorFor的重载,但是将对每个内容项使用相同的模板,但这不是我想要的。

我确实尝试过使用默认模板,基本上

//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或类似工具针对每个项目使用自定义模板吗?

接口

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>

可编辑的SomeType模板

@model SomeTypeEditableContent
//Display this as a editable string

默认可编辑内容模板

@model IEditableContent
//Use default display

抱歉,我没有时间进行测试。 让我知道如何进行,如果没有,我将编辑/删除此答案。 我会将其发布为评论,但是我需要注释和格式。 但是至少它使您对我的想法有所了解。

-编辑-

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

-编辑2(基于注释)-

更改了示例以匹配新规范

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

如果事实证明尝试从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) 
    }
}

然后,从从数据库加载并显示可编辑内容的常规代码中,调用自定义扩展名:

@Html.AndiEditorFor(model)

更新:

更好的选择可能是完全跳过“剃刀生成器”。 只需定义一个自定义的HtmlHelper,模仿EditorExtensions方法即可 添加类似的if / else来处理Model.EditorView是否具有值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM