Polymer 中多态对象集合的模式?
Patterns for collections of polymorphic objects in Polymer?
假设我有两个单独的多态对象列表:Shape -> Circle 和 Shape -> Rectangle。 Shape 包含 "name" 和 "description" 属性,而 Circle 包含 "center" 和 "radius" 属性,而 rectangle 包含 "length" 和 "width" 属性。我想要一个单一的 Polymer 组件,"shape-list",它能够处理圆列表或矩形列表的显示,并显示列表中每种类型的特定属性。
"shape-list" 的模板可能如下所示:
<template>
<ul>
<template is="dom-repeat" items="[[shapes]]" as="shape">
<li>
<shape-entry shape="[[shape]]">
<!-- The user of shape-list knows whether we want to display
Rectangles or Circles. We want to customize the display
of each shape-entry with information specific to each
shape by using some sort of prototype element supplied
to the shape-list tag. -->
<content select="..."></content>
</shape-entry>
</li>
</template>
</ul>
</template>
"shape-entry" 的模板看起来像这样:
<template>
Name: <span>[[shape.name]]</span>
Description: <span>[[shape.description]]</span>
<!-- Ideally we would take the passed-in prototype element and
stamp it out here. -->
<content select="...?"></content>
</template>
此外,我们还有 "shape-circle" 和 "shape-rect" 的模板:
形状圆:
<template>
Center: <span>[[shape.center]]</span>
Radius: <span>[[shape.radius]]</span>
</template>
矩形形状:
<template>
Length: <span>[[shape.length]]</span>
Width: <span>[[shape.width]]</span>
</template>
理想情况下,用法如下所示:
我可以看到两种实现上述目标的方法:
不使用"content"标签,而是在shape-list和shape-entry元素上设置属性为实际原型对象引用或特定形状的名称,然后使用一些魔法 JavaScript 创建基于 属性 的特定形状元素的实例,并手动将所有数据绑定在一起。这会给 assemble 元素和数据绑定带来额外的复杂性。
将"shape-list"和"shape-entry"复制到"rect-list"、"circle-list"和"rect-entry"、"circle-entry",并共享样式和子类型之间的行为。这会导致一些代码重复。
是否有更好的方法来实现上述目标?我(理想情况下)更喜欢完全声明式的方法!
您可以有一个形状列表组件,它使用 "if" 模板来显示适当的形状组件(矩形条目、圆形条目)。每个形状条目都应声明一个共享行为,例如具有所有共享形状行为的 ShapeBehavior 以避免口是心非。
.. inside the dom-repeat
<template is="dom-if" if="{{_isRect(item)}}" >
<rect-entry shape={{item}} ></rect-entry>
</template>
<template is="dom-if" if="{{_isCircle(item)}}" >
<circle-entry shape={{item}} ></circle-entry>
</template>
如果要动态传递应使用的元素,则需要一个编程解决方案。
假设我有两个单独的多态对象列表:Shape -> Circle 和 Shape -> Rectangle。 Shape 包含 "name" 和 "description" 属性,而 Circle 包含 "center" 和 "radius" 属性,而 rectangle 包含 "length" 和 "width" 属性。我想要一个单一的 Polymer 组件,"shape-list",它能够处理圆列表或矩形列表的显示,并显示列表中每种类型的特定属性。
"shape-list" 的模板可能如下所示:
<template>
<ul>
<template is="dom-repeat" items="[[shapes]]" as="shape">
<li>
<shape-entry shape="[[shape]]">
<!-- The user of shape-list knows whether we want to display
Rectangles or Circles. We want to customize the display
of each shape-entry with information specific to each
shape by using some sort of prototype element supplied
to the shape-list tag. -->
<content select="..."></content>
</shape-entry>
</li>
</template>
</ul>
</template>
"shape-entry" 的模板看起来像这样:
<template>
Name: <span>[[shape.name]]</span>
Description: <span>[[shape.description]]</span>
<!-- Ideally we would take the passed-in prototype element and
stamp it out here. -->
<content select="...?"></content>
</template>
此外,我们还有 "shape-circle" 和 "shape-rect" 的模板:
形状圆:
<template>
Center: <span>[[shape.center]]</span>
Radius: <span>[[shape.radius]]</span>
</template>
矩形形状:
<template>
Length: <span>[[shape.length]]</span>
Width: <span>[[shape.width]]</span>
</template>
理想情况下,用法如下所示:
我可以看到两种实现上述目标的方法:
不使用"content"标签,而是在shape-list和shape-entry元素上设置属性为实际原型对象引用或特定形状的名称,然后使用一些魔法 JavaScript 创建基于 属性 的特定形状元素的实例,并手动将所有数据绑定在一起。这会给 assemble 元素和数据绑定带来额外的复杂性。
将"shape-list"和"shape-entry"复制到"rect-list"、"circle-list"和"rect-entry"、"circle-entry",并共享样式和子类型之间的行为。这会导致一些代码重复。
是否有更好的方法来实现上述目标?我(理想情况下)更喜欢完全声明式的方法!
您可以有一个形状列表组件,它使用 "if" 模板来显示适当的形状组件(矩形条目、圆形条目)。每个形状条目都应声明一个共享行为,例如具有所有共享形状行为的 ShapeBehavior 以避免口是心非。
.. inside the dom-repeat
<template is="dom-if" if="{{_isRect(item)}}" >
<rect-entry shape={{item}} ></rect-entry>
</template>
<template is="dom-if" if="{{_isCircle(item)}}" >
<circle-entry shape={{item}} ></circle-entry>
</template>
如果要动态传递应使用的元素,则需要一个编程解决方案。