在 Polymer 中有条件地包装 <content> 个插入点
Conditionally wrapping <content> insertion points in Polymer
我正在尝试制作一个 Polymer 元素,它是一个简单的盒子或容器,包含 3 个主要元素:页眉、正文和页脚。页眉和页脚是可选的,但如果它们在那里,我想在它们周围添加一些东西。
我的问题是如何在 <content>
插入点周围放置一个包装元素,该插入点仅在 select 属性匹配某些内容时出现?
我的代码是这样的(不起作用):
<polymer-element name="example-card" attributes="">
<template>
<paper-shadow z="1">
<div vertical layout>
<div class="card card-header" hidden?="{{!$.header}}">
<content id="header" select=".header"></content>
</div>
<div class="card card-body">
<content id="body" select=":not(.footer)"></content>
</div>
<div class="card card-footer" hidden?="{{!$.footer}}">
<content id="footer" select=".footer"></content>
</div>
</div>
</paper-shadow>
</template>
<script>
Polymer({});
</script>
</polymer-element>
预期用途 - 此示例中没有页脚:
<example-card>
<div class="header">Header...</div>
<div>Body...</div>
</example-card>
如果其内容未被 select 编辑,我要么想隐藏包装 div,要么将其放在 <template if="...">
中以将其从光线中移除 DOM 完全。上面的 hidden?
表达式不起作用。
我尝试了一些不同的方法但没有成功,包括:
hidden?="{{!$.footer.getDistributedNodes().length}}"
是否有任何方法可以根据 selection 是否匹配来有条件地包装插入点?也许我做错了。谢谢!
编辑:感谢 Fuzzical Logic 的帮助,这就是我修改后的版本,它使用 lodash 进行集合过滤,仅 select 直接子项的页眉和页脚 类:
<polymer-element name="example-card" attributes="">
<template>
<paper-shadow z="1">
<div vertical layout>
<template if="{{showheader}}">
<div class="card card-header">
<content id="header" select=".header"></content>
</div>
</template>
<div class="card card-body">
<content select=":not(.footer)"></content>
</div>
<template if="{{showfooter}}">
<div class="card card-footer">
<content id="footer" select=".footer"></content>
</div>
</template>
</div>
</paper-shadow>
</template>
<script>
Polymer({
domReady: function () {
// Doesn't work in IE11...
// this.showheader = this.querySelector(':scope > .header');
// this.showfooter = this.querySelector(':scope > .footer');
this.showheader = _.filter(this.children, function(e) { return e.className === "header"; }).length;
this.showfooter = _.filter(this.children, function(e) { return e.className === "footer"; }).length;
},
publish: {
showheader: {
value: false,
reflect: true
},
showfooter: {
value: false,
reflect: true
}
}
});
</script>
</polymer-element>
问题不在于 hidden?
不工作。 $.header
总是通过 id === "header"
解析为 header(即 this.$.header
)。这意味着它将永远是真实的。解决此问题的最简单方法是在检查 children.
的 domReady
事件中设置属性
Polymer('example-card', {
... other element code ...
domReady: function() {
this.showheader = this.querySelector('.header');
this.showfooter = this.querySelector('.footer');
},
publish: {
showheader: {
value: false,
reflect: true
},
showfooter: {
value: false,
reflect: true
}
},
... other element code ...
});
为了使其正常工作,请按如下方式调整您的元素:
<div class="card card-header" hidden?="{{!showheader}}">
<content id="header" select=".header"></content>
</div>
<div class="card card-footer" hidden?="{{!showfooter}}">
<content id="footer" select=".footer"></content>
</div>
重要提示
上面的 domReady
代码只是一个例子,并不完整,它会在树中从 content
开始找到任何 .header
。正确的方法是只检查 children
.
我正在尝试制作一个 Polymer 元素,它是一个简单的盒子或容器,包含 3 个主要元素:页眉、正文和页脚。页眉和页脚是可选的,但如果它们在那里,我想在它们周围添加一些东西。
我的问题是如何在 <content>
插入点周围放置一个包装元素,该插入点仅在 select 属性匹配某些内容时出现?
我的代码是这样的(不起作用):
<polymer-element name="example-card" attributes="">
<template>
<paper-shadow z="1">
<div vertical layout>
<div class="card card-header" hidden?="{{!$.header}}">
<content id="header" select=".header"></content>
</div>
<div class="card card-body">
<content id="body" select=":not(.footer)"></content>
</div>
<div class="card card-footer" hidden?="{{!$.footer}}">
<content id="footer" select=".footer"></content>
</div>
</div>
</paper-shadow>
</template>
<script>
Polymer({});
</script>
</polymer-element>
预期用途 - 此示例中没有页脚:
<example-card>
<div class="header">Header...</div>
<div>Body...</div>
</example-card>
如果其内容未被 select 编辑,我要么想隐藏包装 div,要么将其放在 <template if="...">
中以将其从光线中移除 DOM 完全。上面的 hidden?
表达式不起作用。
我尝试了一些不同的方法但没有成功,包括:
hidden?="{{!$.footer.getDistributedNodes().length}}"
是否有任何方法可以根据 selection 是否匹配来有条件地包装插入点?也许我做错了。谢谢!
编辑:感谢 Fuzzical Logic 的帮助,这就是我修改后的版本,它使用 lodash 进行集合过滤,仅 select 直接子项的页眉和页脚 类:
<polymer-element name="example-card" attributes="">
<template>
<paper-shadow z="1">
<div vertical layout>
<template if="{{showheader}}">
<div class="card card-header">
<content id="header" select=".header"></content>
</div>
</template>
<div class="card card-body">
<content select=":not(.footer)"></content>
</div>
<template if="{{showfooter}}">
<div class="card card-footer">
<content id="footer" select=".footer"></content>
</div>
</template>
</div>
</paper-shadow>
</template>
<script>
Polymer({
domReady: function () {
// Doesn't work in IE11...
// this.showheader = this.querySelector(':scope > .header');
// this.showfooter = this.querySelector(':scope > .footer');
this.showheader = _.filter(this.children, function(e) { return e.className === "header"; }).length;
this.showfooter = _.filter(this.children, function(e) { return e.className === "footer"; }).length;
},
publish: {
showheader: {
value: false,
reflect: true
},
showfooter: {
value: false,
reflect: true
}
}
});
</script>
</polymer-element>
问题不在于 hidden?
不工作。 $.header
总是通过 id === "header"
解析为 header(即 this.$.header
)。这意味着它将永远是真实的。解决此问题的最简单方法是在检查 children.
domReady
事件中设置属性
Polymer('example-card', {
... other element code ...
domReady: function() {
this.showheader = this.querySelector('.header');
this.showfooter = this.querySelector('.footer');
},
publish: {
showheader: {
value: false,
reflect: true
},
showfooter: {
value: false,
reflect: true
}
},
... other element code ...
});
为了使其正常工作,请按如下方式调整您的元素:
<div class="card card-header" hidden?="{{!showheader}}">
<content id="header" select=".header"></content>
</div>
<div class="card card-footer" hidden?="{{!showfooter}}">
<content id="footer" select=".footer"></content>
</div>
重要提示
上面的 domReady
代码只是一个例子,并不完整,它会在树中从 content
开始找到任何 .header
。正确的方法是只检查 children
.