1

サービスベースの会社の予定を管理するカスタム モジュールを作成しました。現在の機能はすべて管理セクションに含まれています。ContentItem または ContentPart を 1 つも使用していません。すべてのモデルは単なる記録です。

フロントエンドから予定にサインアップする機能を公開するウィジェットを作成しようとしています。部分的なビューと、表示とフォームの送信を処理するコントローラーがありますが、それをフロントエンドのコンテンツ ゾーンの 1 つに配置できるウィジェットに結び付ける方法がわかりません。

私はこれを調査するのにかなりの時間を費やしましたが、従うべき良い道を見つけることができません. (いくつか試してみましたが、最適な結果が得られませんでした)

助言がありますか?

4

2 に答える 2

0

私にとって最良の答えは、モジュールの migration.cs ファイルにウィジェット タイプの定義を作成することでした。

ContentDefinitionManager.AlterTypeDefinition("CreateAppointmentWidget",
    cfg => cfg
        .WithPart("WidgetPart")
        .WithPart("CommonPart")
        .WithSetting("Stereotype", "Widget"));

次に、そのウィジェットのハンドラを で作成します/MyModule/Handlers/CreateAppointmentWidgetHandler.cs

public class CreateAppointmentWidgetHandler : ContentHandler
{
    private readonly IRepository<FieldTechRecord> _repository;

    public CreateAppointmentWidgetHandler(IRepository<FieldTechRecord> repository)
    {
        _repository = repository;
    }

    protected override void BuildDisplayShape(BuildDisplayContext context)
    {
        base.BuildDisplayShape(context);

        if (context.ContentItem.ContentType == "CreateAppointmentWidget")
        {
            CreateAppointmentViewModel model = new CreateAppointmentViewModel(_repository.Fetch(x => x.IsActive));
            context.Shape.AppointmentModel = model;
        }
    }
}

/MyModule/Views/Widget-CreateAppointmentWidget.cshtml次に、部分ビューを挿入する一致するウィジェット テンプレートを作成します。

@Html.Partial("CreateAppointment", (MyModule.Models.Views.CreateAppointmentViewModel)Model.AppointmentModel)

上記のコードは部分ビューを取得します/MyModule/Views/CreateAppointment.cshtml

Giscard の提案のおかげで、@Url.RouteUrl() を使用して CreateAppointment.cshtml からレンダリングされたリンクを修正し、名前付きルートを定義して、アクションと ajax 要求が必要な場所を指すようにすることができました。

このソリューションの優れた点は、Orchards の ContentPart 機能を使用するためにモデルを作り直す必要なく、ウィジェットを作成する方法を提供したことです。

于 2012-04-18T22:28:03.280 に答える
0

@Display.Shape() を実行するだけで、ゾーンを使用してテーマを作成し、モジュールからそのゾーンに形状をディスパッチできたため、頭の中で何かが接続されていません。したがって、ハンドラーを使用してBuildDisplayShape.

繰り返しますが、これはプレーン レコードとしてモデルを使用するシナリオです (ContentItem または ContentPart を使用していない場合でも、それらを使用していない場合でも、移行によってモデルを作成する例を示しました)。

このようなもの - コントローラー:

public ShapeResult MyShape()
{
    var shape = _orchardServices.New.MyPath1_MyShape();
    return new ShapeResult(this, shape);
}

次に、私が持っているコードを使用して MyShape.cshtml シェイプを作成します (例は必要ありません)。

注:IShapeTemplateHarvester図形を保存できるパスを追加するカスタム ファイルを使用します (Orchard のストックである「Views」、「Views/Items」、「Views/Parts」、「Views/Fields」を使用する代わりに)。次のようになります。

NB: コードが SO で自動的にラップされないのが嫌いです。

[OrchardSuppressDependency("Orchard.DisplayManagement
    .Descriptors.ShapeTemplateStrategy.BasicShapeTemplateHarvester")]
public class MyShapeTemplateHarvester : BasicShapeTemplateHarvester,
    IShapeTemplateHarvester
{
    public new IEnumerable<string> SubPaths()
    {
        var paths = base.SubPaths().ToList();
        paths.Add("Views/MyPath1");
        paths.Add("Views/MyPath2");
        return paths;
    }
}

テーマに Index.cshtml があるとします。2 つの選択肢があります (両方を使用し、テーマをデフォルトのプレゼンテーションとして使用します)。

テーマ フォルダー内の Index.cshtml:

@*Default Content*@

Module フォルダー内の Index.cshtml:

@*Special Content overriding Theme's Index.cshtml*@
Display.MyPath1_MyShape()

私にとってさらに良いのは、これを Theme フォルダーの Index.cshtml で実行できることです。

@*Whatever content*@
Display.MyPath1_MySecondShape()

テーマには ~/MyPath1/MySecondShape.cshtml はありませんが、テーマが表示するモジュールには 1 つあります。これは素晴らしいことです。なぜなら、私は特別なテーマを持ち、複数のモジュール (別々のサイトに配置されている) をテーマに沿って行き来させることができるからです (異なるサイトの同じ職業の異なるサービスのダッシュボードを考えてみてください)。

IThemeSelector注: 上記は、次のような実装でのみ可能です。

public class MyThemeSelector : IThemeSelector
{
    public ThemeSelectorResult GetTheme(RequestContext context)
    {
        if (MyFilter.IsApplied(context))
        {
            return new ThemeSelectorResult { Priority = 200,
                ThemeName = "MyDashboard" };
        }

        return null;
    }

}

ちょうど私の2ビット。

于 2013-03-26T17:52:38.387 に答える