0

プロジェクトは現在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などを使用してアイテムごとにカスタムテンプレートを使用する方法についてのアイデアはありますか?

4

2 に答える 2

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>

編集可能なSomeTypeテンプレート

@model SomeTypeEditableContent
//Display this as a editable string

デフォルトの編集可能なコンテンツテンプレート

@model IEditableContent
//Use default display

テストする時間がないのでごめんなさい。どうなるか教えてください。そうでない場合は、この回答を編集/削除します。これをコメントとして投稿したかったのですが、注釈とフォーマットが必要でした。しかし、少なくともそれはあなたに私が何を考えていたかについての考えを与えます。

-編集-

この例のポイントは、MVCフレームワークが、単にインターフェイスとして入力されたオブジェクトを提供する場合でも、実装されたインターフェイスの適切なテンプレートを決定できる必要があることを示すことです。refelction(私は信じますか?)を使用して最高のクラス定義を見つけ、テンプレートを探します。

-編集2(コメントに基づく)-

新しい仕様に一致するように例を変更しました

于 2012-10-01T13:46:11.183 に答える
1

すでにテンプレートをオーバーライドしているビューからエディターテンプレートをオーバーライドしようとしているのは奇妙に思えます。それがうまくいくかどうかはわかりません(うまくいくかもしれませんが、試したことがないのでわかりません)。上記の質問にすでにいくつかコメントを追加しました。

EditorForModel()EditorTemplatesフォルダーからテンプレートを指定しようとしても機能しないことが判明した場合、それは理解できることですが、カスタムオーバーライドを導入することで目的を達成できると思います。DavidEbboのRazorGeneratorVS拡張機能を使用して、プロジェクト全体で使用できるかみそりヘルパーを定義できます。

/// /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)

アップデート:

より良いオプションは、RazorGeneratorを完全にスキップすることです。EditorExtensionsメソッドを模倣して、カスタムHtmlHelperを定義するだけです。同様のif/elseを追加して、値を持つかどうかに関係なくModel.EditorViewを処理します。

于 2012-10-01T13:02:04.687 に答える