我构建了一个自定义模块,用于管理基于服务的公司的约会。所有当前功能都包含在管理部分中。我没有使用单个 ContentItem 或 ContentPart。所有的模型都只是普通的记录。
我正在寻找一个小部件来展示从前端注册约会的能力。我有一个部分视图和一个控制器来处理显示和表单提交,但我不确定如何将其绑定到一个可以放置在前端内容区域之一的小部件中。
我花了相当多的时间研究这个,找不到一个好的路径。(我尝试了一些并得到了次优结果)
有什么建议么?
我构建了一个自定义模块,用于管理基于服务的公司的约会。所有当前功能都包含在管理部分中。我没有使用单个 ContentItem 或 ContentPart。所有的模型都只是普通的记录。
我正在寻找一个小部件来展示从前端注册约会的能力。我有一个部分视图和一个控制器来处理显示和表单提交,但我不确定如何将其绑定到一个可以放置在前端内容区域之一的小部件中。
我花了相当多的时间研究这个,找不到一个好的路径。(我尝试了一些并得到了次优结果)
有什么建议么?
对我来说最好的答案是在模块的 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() 并定义命名路由指向我需要执行操作和 ajax 请求的位置来更正从 CreateAppointment.cshtml 呈现的链接。
这个解决方案的好处是它提供了一种创建小部件的方法,而无需重新设计我的模型以使用 Orchards ContentPart 功能。
我的脑海中没有任何联系,因为我已经能够创建一个带有区域的主题,然后将我的模块中的一个形状发送到该区域,而不仅仅是执行@Display.Shape()。所以我很好奇是否绝对有必要使用处理程序来覆盖BuildDisplayShape
.
同样,这是在您将模型作为普通记录的情况下(不使用 ContentItem 或 ContentPart - 即使不使用它们,您也展示了通过迁移创建模型的示例)。
像这样的东西 - 控制器:
public ShapeResult MyShape()
{
var shape = _orchardServices.New.MyPath1_MyShape();
return new ShapeResult(this, shape);
}
然后使用我拥有的任何代码创建一个 MyShape.cshtml 形状(例如不需要)。
注意:我使用了一个自定义IShapeTemplateHarvester
文件,它添加了可以存储我的形状的路径(而不是使用“视图”、“视图/项目”、“视图/零件”、“视图/字段”,这是 Orchard 的库存)。它是这样的:
注意:我讨厌代码不会自动包装在 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。我有两个选择(我同时使用并使用主题作为默认演示)。
主题文件夹中的 Index.cshtml:
@*Default Content*@
模块文件夹中的 Index.cshtml:
@*Special Content overriding Theme's Index.cshtml*@
Display.MyPath1_MyShape()
对我来说更好的是,我可以在 Theme 文件夹中的 Index.cshtml 中执行此操作:
@*Whatever content*@
Display.MyPath1_MySecondShape()
Theme 中没有 ~/MyPath1/MySecondShape.cshtml,但 Module 中有一个,主题显示!这很棒,因为我可以有一个特殊的主题,并且有多个模块(放置在不同的站点上)与主题来回切换(想想不同站点上同一专业的不同服务的仪表板)。
注意:上述情况可能仅适用于以下IThemeSelector
实施:
public class MyThemeSelector : IThemeSelector
{
public ThemeSelectorResult GetTheme(RequestContext context)
{
if (MyFilter.IsApplied(context))
{
return new ThemeSelectorResult { Priority = 200,
ThemeName = "MyDashboard" };
}
return null;
}
}
只是我的两个位。