我有这个应用程序,其中包含许多类型的聚合物元素,可以添加到主要的聚合物应用程序元素中。此主元素管理这些元素的实例并在 UI 中显示它们。
例如。
- 项目1.html
- 项目2.html
- 项目3.html
- 我的应用.html
当我添加新类型的项目(例如 item4.html)时,我需要对主 UI 进行一些更改来处理它们的创建、管理和显示。每种类型都足够独特,我不想将它们合并为单个项目类型。
我想做的是通过调用一个可以将新对象添加到数组的函数,让每个 Polymer 元素将自己"注册"到 my-app 中。
为此,my-app 将具有一个名为itemMap
的属性,该属性是一个对象数组。此对象中的一个属性是项的类型。
itemMap: [
{
type: 'item-1',
instances: []
}, {
type: 'item-2',
instances: []
}
...
]
此实现在代码中工作。添加新实例时,我可以将该类型的instances
数组添加一个新对象。但是,我不知道如何在UI中显示项目。由于每种类型都是不同的聚合物元素,因此我不能使用简单的dom-repeat
模板。同时,我不想在主 UI 中对每种类型进行硬编码以提高模块化。
现在我有:
<iron-list id="item-1-list" items="[[item1_array]]" as="item" grid>
<template>
<div class="item">
<item-1 properties=[[item]]></item-1>
</div>
</template>
</iron-list>
<iron-list id="item-2-list" items="[[item2_array]]" as="item" grid>
<template>
<div class="item">
<item-2 properties=[[item]]></item-2>
</div>
</template>
</iron-list>
我想做的是类似于下面的代码片段,它适用于我创建的任何类型。
<template is="dom-repeat" items="{{itemMap}}" as="itemType" id="item-grid">
<iron-list id="[[itemType.type]]-list" as="item" grid items="[[itemType.instances]]">
<template>
<div class="item">
<[[itemType.type]] properties=[[item]]></[[itemType.type]]>
</div>
</template>
</iron-list>
</template>
但是,这不起作用。
这是可能的,还是等效的,还是我完全走错了路?
聚合物数据绑定不适用于标记名称。要实现这种行为,您可以做的是创建另一个自定义元素,该元素接受项类型作为属性并动态创建该类型的元素:
<template is="dom-repeat" items="{{itemMap}}" as="itemType" id="item-grid">
<iron-list id="[[itemType.type]]-list" as="item" grid items="[[itemType.instances]]">
<template>
<div class="item">
<x-item-selector type=[[itemType.type]] properties=[[item]]></x-item-selector>
</div>
</template>
</iron-list>
</template>
可以通过多种方式实现x-item-selector
元素:声明式和命令式:
声明性:创建一组
<dom-if>
- 每种类型一个如果只有几种元素类型,并且您可以列出所有元素类型,则可以为
x-item-selector
创建一个模板,如下所示:<template> <template is="dom-if" if="[[_isEqual(type, 'item-1')]]" restamp> <item-1 properties="[[properties]]"></item-1> </template> ... </template>
命令性:观察
type
属性并手动更新子元素如果要支持多种类型的元素,则可能需要避免大量
<dom-if>
,并在type
属性更改时强制更新x-item-selector
元素的子元素。不利的一面是,您还必须手动建立properties
属性的映射。_onTypeChanged(newType, oldType) { if (newType !== oldType) { for (let child of this.children) { this.removeChild(child); } const newChild = document.createElement(newType); newChild.properties = this.properties; // also need to add some code to update newChild.properties // when this.properties change this.appendChild(newChild); } }