我正在通过Polymer工作。我试图找出如何在iron-collapse
中使用dom-repeat
元素。目前,我有以下内容:
<template is="dom-repeat" items="[[ data ]]" as="child">
<div class="child-item">
<div class="info" on-click="_toggleClick">
<paper-item>
<iron-icon icon="arrow-drop-up" class="rotate-90"></iron-icon>
<span>[[ child.name ]]</span>
</paper-item>
</div>
<iron-collapse opened="false">
<div>Details for child go here</div>
</iron-collapse>
</div>
</template>
...
<script>
Polymer({
is: 'child-details',
properties: {
data: {
type: Array,
value: function() {
return [];
}
},
},
_toggleClick: function(e, detail) {
try {
var arrowElement = document.querySelector('iron-icon');
arrowElement.classList.toggle('rotate-clockwise-90');
} catch (ex) {
console.log('Unable to rotate arrow.');
console.log(ex);
}
try {
var element = Polymer.dom(parent).querySelector('iron-collapse');
element.toggle();
} catch (ex) {
console.log('Unable to toggle iron-collapse.');
console.log(ex);
}
}
});
</script>
当我点击div
时,我在控制台窗口中看到以下内容:
Unable to toggle iron-collapse.
TypeError: Cannot read property 'toggle' of undefined(...)
我不确定为什么找不到iron-collapse
元素。同时,classList切换开始应用于页面上的第一个iron-icon
元素,而不是像我期望的那样iron-icon
中的第一个dom-repeat
元素。我也不明白这一点。
感谢任何帮助!
答案 0 :(得分:2)
您的选择者
document.querySelector('iron-icon');
var element = Polymer.dom(parent).querySelector('iron-collapse');
有几个方面存在缺陷。
document
开始,但您想从当前元素开始。 第二个从parent
开始,这不是更好
您创建了多个iron-collapse
,选择第一个找到的&#34;任何地方&#34;是什么。你想要点击的那个。
改为使用
var div = Polymer.dom(e).rootTarget;
div.querySelector('iron-icon').classList.toggle('rotate-clockwise-90')
div.querySelector('iron-collapse').toggle();
答案 1 :(得分:0)
我猜测孩子们没有唯一的ID,所以我使用了从dom-repeat生成的变量index
。索引将是您获得点击事件的div的id
。
我在事件方法_toggleClick
中设置了该元素的ID来设置变量currentOpenedCollapsable
。更新时,它会更新所有opened
上的iron-collapsables
以及名为child-item
的div容器上的样式表。后者将使铁图标旋转。
总而言之,更少的javascript代码,一个添加的变量和一个添加的方法。使用querySelector减少循环,使用更多可恢复的方法和更多功能(单击时关闭相同的元素)。
<style>
.opened iron-icon {
transform: rotateZ(180deg);
transition: transform 0.3s;
}
</style>
<template is="dom-repeat" items="[[ data ]]" as="child">
<div class$="child-item [[isOpenedBasedOn(index, currentOpenedCollapsable)]]">
<div class="info" id="[[index]]" on-click="_toggleClick">
<paper-item>
<iron-icon icon="arrow-drop-up"></iron-icon>
<span>[[ child.name ]]</span>
</paper-item>
</div>
<iron-collapse opened="[[isOpenedBasedOn(index, currentOpenedCollapsable)]]">
<div>Details for child go here</div>
</iron-collapse>
</div>
</template>
...
<script>
Polymer({
is: 'child-details',
properties: {
data: {
type: Array,
value: function() {
return [];
}
},
currentOpenedCollapsable: {
type: Number,
value: -1
}
},
// set index, but close (set to -1) if clicking on the same element.
_toggleClick: function(e) {
var currentIndex = e.currentTarget.id
if (this.currentOpenedCollapsable == currentIndex) {
currentIndex = -1;
}
this.set('currentOpenedCollapsable', currentIndex);
},
// Using the javascript fact that a filled string is always true while an empty string is always false
isOpenedBasedOn: function(elementIndex, currentIndex) {
return (elementIndex == currentIndex) ? 'opened' : '';
},
});
</script>