【问题标题】:Orchard Custom Widget with Form带有表单的果园自定义小部件
【发布时间】:2012-04-29 07:51:22
【问题描述】:

我构建了一个自定义模块,用于管理基于服务的公司的约会。所有当前功能都包含在管理部分中。我没有使用单个 ContentItem 或 ContentPart。所有的模型都只是普通的记录。

我正在寻找创建一个小部件以公开从前端注册约会的能力。我有一个部分视图和一个控制器来处理显示和表单提交,但我不确定如何将其绑定到一个可以放置在前端内容区域之一的小部件中。

我花了相当多的时间研究这个,但找不到一个好的路径。 (我尝试了一些并得到了次优结果)

有什么建议吗?

【问题讨论】:

  • 由于任何特殊原因,表单是否必须通过小部件放置在前端,或者您可以使用形状吗?从您的小部件中,您可以在局部视图上调用 @Html.RenderPartial()。它看起来很简单(也许我缺少一些东西)。您是否有任何特定的部分被卡住或有疑问?您是否查看过 Orchard 文档中的 Widget 创建信息?
  • 不,它不一定是小部件。我不确定如何使用形状来解决问题。我已经阅读了有关创建小部件的果园文档以及其他教程。它们都基于内容部分的小部件,除了我发现的一个按照你的建议做的。我尝试过使用@Html.RenderPartial(),当它渲染视图时,一些关键的ajax调用被破坏了,因为@Url.Action("GetServices", "Appointment")返回了错误的路径:localhost:30320/OrchardLocal/Contents/Appointment/GetServices而不是:@ 987654322@
  • 尝试命名您的路线并使用@Url.RouteUrl() 作为一种简单的方法来强制您想要的路线。
  • 另外,在使用Url.Action时,需要指定区域。
  • @BertrandLeRoy 指定操作没有任何区别。 @GiscardBiamby 我爱你。那行得通。我能够使用 @Url.RouteUrl() 指定特定路径,让表单在小部件中正常工作。

标签: asp.net asp.net-mvc-3 orchardcms


【解决方案1】:

我的脑子里有些东西没有联系,因为我已经能够创建一个带有区域的主题,然后将我的模块中的一个形状发送到该区域,而无需执行@Display.Shape()。所以我很好奇是否绝对有必要使用处理程序来覆盖BuildDisplayShape

同样,这是在您将模型作为普通记录的情况下(不使用 ContentItem 或 ContentPart - 即使不使用它们,您也展示了通过迁移创建模型的示例)。

类似这样的东西 - 控制器:

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

然后使用我拥有的任何代码创建一个 MyShape.cshtml 形状(例如,不需要)。

注意:我使用自定义 IShapeTemplateHarvester 文件,它添加了可以存储我的形状的路径(而不是使用“视图”、“视图/项目”、“视图/零件”、“视图/字段”,即果园的库存)。它是这样的:

注意:我讨厌代码不会自动包装在 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中有一个,Theme会显示!这很棒,因为我可以有一个特殊的主题,并且有多个模块(放置在不同的站点上)与主题来回切换(想想不同站点上同一专业的不同服务的仪表板)。

注意:以上可能仅适用于 IThemeSelector 实现,例如:

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

        return null;
    }

}

只有我的两个位。

【讨论】:

    【解决方案2】:

    对我来说最好的答案是在模块的 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() 并定义 named 路由来更正从 CreateAppointment.cshtml 呈现的链接,以指向我需要操作和 ajax 请求的位置去吧。

    这个解决方案的好处在于,它提供了一种创建小部件的方法,而无需修改我的模型以使用 Orchards ContentPart 功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多