在我的组件中,我想重复一个项目列表,其中包含由组件的光源提供的模板。例如:
<template is="dom-repeat" items="{{items}}">
<content select="#itemTemplate"></content>
</template>
然而,似乎Polymer只将一个轻量级元素#itemTemplate插入一次而不是多次。有没有其他方法来重复轻dom元素?
答案 0 :(得分:2)
我创建了一个简单的原型,可以让你指定轻量级DOM模板的重复次数。
因为内容在轻量级DOM中,所以您可以像往常一样从外部设置样式。模板中的数据绑定也有效,因为我已经实现了_forwardParentProp
中的_forwardParentPath
和Templatizer
方法。
请注意,我不实现了特定于实例的属性,这将允许每行特定变量,例如index
和item
。当然,这可以完成,但需要更多的工作。
查看原型: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);
}
},
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>