html - dom-repeat中的聚合物动态元素名称

原文 标签 html polymer polymer-2.x

Polymer dynamic element name in dom-repeat

how can I use dom-repeat to create different elements for iron-pages? something like this:

<template is="dom-repeat" items="{{pages}}">
  <[[item.name]]></[[item.name]]>
</template>

...

pages: {
  type: Array,
  value() {
    return [
      {
        "name": "element-a",
      },
      {
        "name": "element-b",
      },
      {
        "name": "element-c",
      },
},

I'm using polymer 2.0.

Answer

since my comment had some interest, I put it as an answer.

The code examples will be in polymer 1.9 for now, I'll update my answer when I'll do the switch to 2.0 but the idea should be the same anyway

First you need a wrapper element, wich will be capable of creating another element dynamically from a property, and adding it to itself. In my example the name of the element to create will be a property named type of a JSON object Data wich came from a database in XHR.

With a dynamically created element the binding won't work, so you have to do it by hand. That's what the _updateStatefunction is for, here it only update on one property but the idea is the same is there is more.

wrapper :

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../styles/shared-styles.html">

<dom-module id="element-wrapper">
    <template></template>
    <script>
        Polymer({
            is: 'element-wrapper',
            properties: {
                elementData: {
                     type: Object
                },
                saveFbPath: {
                    type: String
                },
                element: {
                    type: Object
                },
                formSubmitPressed: {
                    type: Boolean,
                    value: false
                }
            },
            observers: [
                '_updateState(elementData.*)'
            ],
            attached: function () {
                console.log("creating element : ", this.elementData);
                this.async(function () {
                    this.element = this.create(this.elementData.type, {
                        "data": this.elementData
                    });
                    this.appendChild(this.element);
                }.bind(this));
            },
            _updateState: function (elementData) {
                if (typeof this.element !== "undefined") {
                    this.element.data = elementData.value;
                    console.log('Change captured', elementData);
                }
            }
        });
    </script>
</dom-module>

The this.element = this.create(this.elementData.type, {"data":this.elementData}); line is the one creating the element, first argument is the dom-modulename, and the second a JSON object wich will be binded to the properties of the element. this.appendChild(this.element);will then add it to the dom

All this is in a this.async call for a smoother display

You then need a dom-repeat which will call this element, and give it the datas it need to create the dynamic ones. Here is an example of an element-list but you don't necessary need a specific element for that, this logic can be in a bigger one.

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../styles/shared-styles.html">

<link rel="import" href="element-wrapper">
<dom-module id="element-list">
    <template>
        <style is="custom-style" include="shared-styles"></style>
        <template is="dom-repeat" items="[[ datas ]]" initial-count="10" as="data">
            <element-wrapper element-data="[[data]]"></element-wrapper>
        </template>
    </template>
    <script>
        Polymer({
            is: 'element-list',
            properties: {
                datas: {
                    type: Array,
                    value: function () {
                        return [];
                    }
                }
            }
        });
    </script>
</dom-module>

This should do the trick :)

翻译

如何使用dom-repeat为铁页创建不同的元素?像这样的东西:

<template is="dom-repeat" items="{{pages}}">
  <[[item.name]]></[[item.name]]>
</template>

...

pages: {
  type: Array,
  value() {
    return [
      {
        "name": "element-a",
      },
      {
        "name": "element-b",
      },
      {
        "name": "element-c",
      },
},


我正在使用聚合物2.0。
最佳答案
由于我的评论引起了兴趣,我将其作为答案。

该代码示例目前将在聚合物1.9中,当我切换到2.0时,我将更新答案,但是无论如何,想法应该是相同的

首先,您需要一个wrapper元素,该wich将能够从属性动态创建另一个元素,并将其添加到自身。
在我的示例中,要创建的元素的名称将是JSON对象的名为type的属性。数据来自XHR中的数据库。

对于动态创建的元素,绑定将不起作用,因此您必须手动进行。这就是_updateState函数的作用,这里它仅对一个属性进行更新,但想法是相同的,只是还有更多。

包装器:

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../styles/shared-styles.html">

<dom-module id="element-wrapper">
    <template></template>
    <script>
        Polymer({
            is: 'element-wrapper',
            properties: {
                elementData: {
                     type: Object
                },
                saveFbPath: {
                    type: String
                },
                element: {
                    type: Object
                },
                formSubmitPressed: {
                    type: Boolean,
                    value: false
                }
            },
            observers: [
                '_updateState(elementData.*)'
            ],
            attached: function () {
                console.log("creating element : ", this.elementData);
                this.async(function () {
                    this.element = this.create(this.elementData.type, {
                        "data": this.elementData
                    });
                    this.appendChild(this.element);
                }.bind(this));
            },
            _updateState: function (elementData) {
                if (typeof this.element !== "undefined") {
                    this.element.data = elementData.value;
                    console.log('Change captured', elementData);
                }
            }
        });
    </script>
</dom-module>


this.element = this.create(this.elementData.type, {"data":this.elementData});行是创建元素的行,第一个参数是dom-module name,第二行是将绑定到元素属性的JSON对象。
this.appendChild(this.element);然后将其添加到dom

所有这些都在this.async调用中以实现更流畅的显示

然后,您需要一个dom-repeat,它将调用此元素,并为它提供创建动态数据所需的数据。
这是一个element-list的示例,但是您不必为此指定特定的元素,这种逻辑可以包含在更大的逻辑中。

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../styles/shared-styles.html">

<link rel="import" href="element-wrapper">
<dom-module id="element-list">
    <template>
        <style is="custom-style" include="shared-styles"></style>
        <template is="dom-repeat" items="[[ datas ]]" initial-count="10" as="data">
            <element-wrapper element-data="[[data]]"></element-wrapper>
        </template>
    </template>
    <script>
        Polymer({
            is: 'element-list',
            properties: {
                datas: {
                    type: Array,
                    value: function () {
                        return [];
                    }
                }
            }
        });
    </script>
</dom-module>


这应该可以解决问题:)
相关推荐

javascript - IE11 / Edge不遵守DOM中的链接/ css顺序

javascript - Web2py无法滚动到页面底部

html - 调整表格大小时的Chrome渲染错误,标题背景贴在另一个div顶部

javascript - 拖放多个浏览器窗口/选项卡

javascript - 动态访问JavaScript数组

html - (S)CSS体系结构:替代背景样式

javascript - 如何在Edge浏览器中打印背景图像和颜色

javascript - AngularJS:如何在编辑模式下以ng-repeat冻结orderBy

html - 两个固定元素的z-index不起作用

html - Angular 2:动态创建div