重复轻dom元素

时间:2015-09-28 07:44:32

标签: polymer polymer-1.0

在我的组件中,我想重复一个项目列表,其中包含由组件的光源提供的模板。例如:

<template is="dom-repeat" items="{{items}}">
    <content select="#itemTemplate"></content>
</template>

然而,似乎Polymer只将一个轻量级元素#itemTemplate插入一次而不是多次。有没有其他方法来重复轻dom元素?

2 个答案:

答案 0 :(得分:2)

我创建了一个简单的原型,可以让你指定轻量级DOM模板的重复次数。

因为内容在轻量级DOM中,所以您可以像往常一样从外部设置样式。模板中的数据绑定也有效,因为我已经实现了_forwardParentProp中的_forwardParentPathTemplatizer方法。

请注意,我实现了特定于实例的属性,这将允许每行特定变量,例如indexitem。当然,这可以完成,但需要更多的工作。

查看原型:JSBin

好的,让我们详细说明一下:

test-element的使用以及对input个元素的数据绑定非常简单:

<template is="dom-bind">
    Number of repeats: <input type="text" value="{{repeats::input}}" /> <br />
    Custom message: <input type="text" value="{{customMessage::input}}" />

    <test-element repeats="{{repeats}}">
        <template>
            <h1>Title!</h1>

            <p>
                Custom message: <em>[[customMessage]]</em>
            </p>
        </template>
    </test-element>
</template>

注意dom-bind,这是创建数据绑定范围所必需的。

对于test-element,整个源代码如下所示:

<dom-module id="test-element">
    <template>
      <style>
        :host {
          display: block;
        }
      </style>

          <content></content>
    </template>

    <script>
        Polymer({

            is: 'test-element',

            behaviors: [
                Polymer.Templatizer,
            ],

            properties: {
                repeats: {
                    type: Number,
                    value: 3,
                    notify: true,
                },
            },

            observers: [
                '_repeatsChanged(repeats)',
            ],

            _repeatsChanged: function(repeats) {
                // First time only: initialize template
                if (this.template === undefined) {
                    this.template = Polymer.dom(this).querySelector('template');
                    this.templatize(this.template);
                }

                // Remove previously stamped children
                while (Polymer.dom(this).firstChild) {
                    Polymer.dom(this).removeChild(Polymer.dom(this).firstChild);
                }

                // Stamp new ones
                this.stamped = new Array(repeats);

                var inst;
                for (var i = 0; i < repeats; i++) {
                    inst = this.stamp(null);
                    this.stamped[i] = inst.root.querySelector('*');
                    Polymer.dom(this).appendChild(inst.root);
                }
            },

            // Copied from iron-list
            _forwardParentProp: function(prop, value) {
                if (this.stamped) {
                    this.stamped.forEach(function(item) {
                        item._templateInstance[prop] = value;
                    }, this);
                }
            },

            // Copied from iron-list
            _forwardParentPath: function(path, value) {
                if (this.stamped) {
                    this.stamped.forEach(function(item) {
                        item._templateInstance.notifyPath(path, value, true);
                    }, this);
                }
            },

        });
    </script>
</dom-module>

只有一个属性repeats,它指定标记实例的数量。默认值为3。为了适应所述属性值的更改,已创建observer。这也是冲压发生的地方:

_repeatsChanged: function(repeats) {
    // First time only: initialize template
    if (this.template === undefined) {
        this.template = Polymer.dom(this).querySelector('template');
        this.templatize(this.template);
    }

    // Remove previously stamped children
    while (Polymer.dom(this).firstChild) {
        Polymer.dom(this).removeChild(Polymer.dom(this).firstChild);
    }

    // Stamp new ones
    this.stamped = new Array(repeats);

    var inst;
    for (var i = 0; i < repeats; i++) {
        inst = this.stamp(null);
        this.stamped[i] = inst.root.querySelector('*');
        Polymer.dom(this).appendChild(inst.root);
    }
},
  • 首先(只有一次),从轻量级DOM中读取模板 调用templatize方法。这个方法初始化了 Templatize行为。
  • 其次,所有以前盖章的孩子都被移除(这样就可以了 元素不会无限制地建立起来。
  • 第三,根据目前的价值,新生儿被加盖印章 repeats。所有标记的实例都保存到this.stamped,其中 从外部到工作的数据绑定需要。

最后但并非最不重要的是,Templatizer行为是通过两种方法实现的(其中两种未实现):

// Copied from iron-list
_forwardParentProp: function(prop, value) {
        if (this.stamped) {
                this.stamped.forEach(function(item) {
                        item._templateInstance[prop] = value;
                }, this);
        }
},

// Copied from iron-list
_forwardParentPath: function(path, value) {
        if (this.stamped) {
                this.stamped.forEach(function(item) {
                        item._templateInstance.notifyPath(path, value, true);
                }, this);
        }
},

这两种方法均来自iron-list。他们遍历标记的子项并传播属性更改和路径通知。

答案 1 :(得分:0)

您可以将您的内容包含在单独的元素中并使用它。

<template is="dom-repeat" items={{items}}">
  <child-element item=[[item]]></child-element>
</template>