我可以使用聚合物数据绑定更改元素标签名称吗?



我有这个应用程序,其中包含许多类型的聚合物元素,可以添加到主要的聚合物应用程序元素中。此主元素管理这些元素的实例并在 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);
    }
    }
    

最新更新