关于Web组件:有条件地将<content>插入点package在Polymer中

Conditionally wrapping <content> insertion points in Polymer

我正在尝试制作一个Polymer元素,它是一个包含3个主要元素的简单盒子或容器:页眉,正文和页脚。页眉和页脚是可选的,但是如果它们在那里,我想在它们周围放一些东西。

我的问题是如何将package元素放在<content>插入点周围,该插入点仅在select属性匹配某些内容时出现?

我的代码是这样的(不起作用):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<polymer-element name="example-card" attributes="">
    <template>
        <paper-shadow z="1">
           
               
                    <content id="header" select=".header"></content>
               
               
                    <content id="body" select=":not(.footer)"></content>
               
               
                    <content id="footer" select=".footer"></content>
               
           
        </paper-shadow>
    </template>
   
        Polymer({});
   
</polymer-element>

预期用途-在此示例中没有页脚:

1
2
3
4
<example-card>
    Header...
    Body...
</example-card>

如果不选择packagediv的内容,我要么想隐藏它,要么将其放在<template if="...">中以从轻型DOM完全摆脱它。上面的hidden?表达式不起作用。

我尝试了几项不同的尝试,但均未成功,包括:

1
hidden?="{{!$.footer.getDistributedNodes().length}}"

有没有办法根据插入点的选择是否匹配来有条件地对其进行package?也许我要解决所有这些错误。谢谢!

编辑:感谢Fuzzical Logic的帮助,这是我的修订版本,它使用lodash进行集合过滤以仅选择直接子级的页眉和页脚类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<polymer-element name="example-card" attributes="">
    <template>
        <paper-shadow z="1">
           
                <template if="{{showheader}}">
                   
                        <content id="header" select=".header"></content>
                   
                </template>
               
                    <content select=":not(.footer)"></content>
               
                <template if="{{showfooter}}">
                   
                        <content id="footer" select=".footer"></content>
                   
                </template>
           
        </paper-shadow>
    </template>
   
    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
            }
        }

    });
   
</polymer-element>

问题不是hidden?无法正常工作。就是$.header总是解析为id ==="header"的标题(即this.$.header)。这意味着它将永远是真实的。解决此问题的最简单方法是在检查子项的domReady事件中设置属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 ...

});

为了使其正常工作,请按如下所示调整元素:

1
2
3
4
    <content id="header" select=".header"></content>


    <content id="footer" select=".footer"></content>

重要说明

上面的domReady代码只是一个示例,并不完整,并且将从content开始在树中找到任何.header。正确的方法是仅检查children