6

我一直在使用 EPiServer 7 MVC 并浏览了 Joel Abrahamsson 的Alloy MVC Template。在查看了自定义的预览控制器后,它以 4 种不同的“大小”预览了一个可以渲染的块,我想到了创建一个特定于某个块“大小”的属性,以便标题文本用于例如,可以根据块呈现的“大小”显示不同的内容。本质上,这将是一个字典,其中键是“大小”,值将包含字符串内容。

有没有人制作过这样的 Dictionary 属性?

我尝试了几种方法,但都被每一种都卡住了:

  1. 自定义属性类型/自定义值类型。按照这个关于创建自定义属性类型的示例(http://joelabrahamsson.com/creating-a-custom-episerver-property-with-a-custom-class-as-value/)我创建了一个自定义属性类型(PropertyDicitionaryString ) 和自定义值类型 (DictionaryString)。我可以通过实现一个显示模板来很好地显示该值,该模板接收具有大小的标签,然后将 Model.MyDictionaryString[ViewData["Tag"] 呈现为字符串]。但是,我还没有弄清楚如何使内联编辑工作,因为不支持对 @Html.EditAttributes(x => x.MyDictionaryString[ViewData["Tag"] as string]) 的调用;该方法不支持 lambda 表达式中的索引或方法调用)。 有人知道如何创建这样的内联编辑器吗?

  2. 自定义属性类型/原始类型。我对上面的自定义属性类型进行了重新设计,我们称之为 (PropertyDictionaryStringAsPrimitive),以便 Value 属性返回一个字符串。这允许我将我的模型定义为:

    [BackingType(typeof(PropertyDictionaryStringAsPrimitive)] public virtual string SizeSpecificString{get;set;}

    当调用它的 Value 方法以确保它返回正确的值时,我必须以某种方式让 PropertyDictionaryStringAsPrimitive 接收当前渲染上下文中的“大小”。我可以通过实现自定义 ContentDataInterceptor 来做到这一点,它会查找对 PropertyDictionaryStringAsPrimitive.Value 的调用并适当地设置 Key。所以现在显示值工作正常,但内联编辑也不太工作。当进行 ajax 保存调用时,我需要添加一些状态信息,以便我可以告诉 PropertyDictionaryStringAsPrimitive 使用哪个键来保存更改。 任何人都知道如何在内联编辑ajax保存请求期间传递额外的状态信息?

  3. 我看了一下[CultureSpecific]属性。如果我可以使用与 CultureSpecific 类似的机制来保留值的“大小”特定实例,那将会很有趣。在反编译器中花费了一些时间试图找出 hwo CultureSpecific 的魔力后,我跟踪了 CotnentDataAttributeScanningAssigner.AssignValuesToPropertyDefinition 的属性,将 PropertyDefinitionModel.CultureSpecific 标志设置为 true,PropertyDefinitionSynchronizer.CreatePropertyDefintion 使用该标志将 PropertyDefintiionModel.CultureSpecificValue 设置为枚举。但我找不到此设置如何影响加载哪个值。 任何人都知道如何使用属性级别属性来动态更改值?

4

1 回答 1

3

I usually avoid custom property types, I prefer sticking to custom editors (where needed) and a block property (or blocks in a content area) for the property values.

Perhaps a viable approach would be to:

1) Create a block type like SizeSpecificHeadingBlock with:

  1. A string property called Size with a SelectOne attribute configured for a SelectionFactory returning the valid size boundary options
  2. Another string property Heading for the actual heading text

Next you could add a ContentArea with AllowedTypes set to SizeSpecificHeadingBlock.

When rendering the ContentArea, you'd simply render the heading for the current size.

However, this would require editors to create one block per heading variation, which is a bit cumbersome - but you could complement this approach with a custom editor to simplify the process.

Using a native way to store property values (instead of a custom property type) makes your implementation more future-proof. Also, if your custom editor should ever fail, you can always disable it and just use the "vanilla" EPiServer UI to editor your property values.

Edit: Although currently in beta, it might be relevant to make use of PropertyList<YourCustomType> for this kind of scenario, to avoid having to create nested blocks: http://world.episerver.com/blogs/Per-Magne-Skuseth/Dates/2015/11/trying-out-propertylistt/

于 2015-04-08T18:21:39.457 回答