将分布式子项追加到Polymer中的<content>元素

时间:2015-11-30 02:48:47

标签: dom polymer shadow-dom

我有一个简单的Polymer元素:

<link rel="import" href="bower_components/polymer/polymer.html">


<dom-module id="observing-test">
  <template>
    <p>This is the title:</p>
    <content id="top" select="#title"></content>
    <p>This is the content:</p>
    <content id="bottom" select="#content"></content>
  </template>

  <script>
    Polymer( {
      is: 'observing-test',

      ready: function(){
        console.log("Ready!");

        Polymer.dom( this.$.top ).observeNodes( function( info ) {
          console.log(" TOP CHANGED!", info );
        });

        Polymer.dom( this.$.bottom ).observeNodes( function( info ) {
          console.log(" BOTTOM CHANGED!", info );
        });
      },

      attached: function(){
        console.log("Attached!");
        OT = this;
      }

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

基本用法:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="description" content="The basic page">
  <meta name="author" content="Tony Mobily">
  <title>The title</title>
  <link rel="import" href="test-component.html">
</head>

<body>

<observing-test>
  <div id="title"><p>TITLE!</p></div>
  <div id="content"><p>CONTENT!</p></div>
</observing-test>

</body>

现在,观察到添加到#top#bottom的所有内容。

那么,如何将一个孩子附加到#top <content>元素以便观察者被触发?

如果我从本地DOM(来自控制台)到达该元素:MAYBE = Polymer.dom( OT ).children[0](这将是<div id="title">,然后Polymer.dom( MAYBE ) .appendChild( document.createElement( 'p' ) ),新元素将添加到{{1}但是,观察者不会被触发(因为我将一个孩子添加到<div>而不是<div>的父母,我认为这是正在观看的内容。)

所以问题:

  • 在观察本地DOM中的<div>元素时,如何从那里追加删除节点?基本上,我想在<content>个元素中添加一个额外的子元素,以便<content>返回一个额外的元素

  • 观察时,我是否会收到直接对其中一个节点的孩子所做的更改的通知?大孩子的修改不起泡,对吧?在定位OT.getContentChildren('#top')元素时,我实际观察了什么?

2 个答案:

答案 0 :(得分:1)

  • <content>是一个DOM插入点(我不会试图详细解释它是什么,Polymer's dev guide比我更好)。基本上,组件中与select节点的<content>查询匹配的每个轻DOM子项都将插入其中。

    因此,要在<content>节点中插入另一个子节点,您必须将与其select查询匹配的子节点添加到组件的轻量级DOM中。

    要做到这一点,你应该更改select查询以定位ID以外的东西(即类或属性),如下所示:

在元素的dom-module中:

 <content id="top" select=".title"></content>

用法:

 <observing-test id="ot">
   <p class=".title">TITLE!</p>
   <div id="content"><p>CONTENT!</p></div>
 </observing-test>

 var newTitleNode = document.createElement( 'p' );
 newTitleNode.className = "title";
 Polymer.dom( this.$.ot ).appendChild( newTitleNode );
  • Polymer observeNodes用于检测本地DOM插入点中节点的添加/删除。你在这里做的是将节点附加到一个轻的DOM节点,该节点本身插入content插入点,你不是直接插入另一个节点。我相信这就是你没有得到通知的原因。

希望这有助于你,某个地方的人可能比我更好地解释这一点。

答案 1 :(得分:1)

还张贴了我自己的答案,这是由文森特(谢谢!)

提出的

如果您有这样的元素:

    <link rel="import" href="bower_components/polymer/polymer.html">
    <dom-module id="observing-test">
      <template>
        <p>This is the list of lines:</p>
        <content id="c" select=".line"></content>
      </template>

      <script>
        Polymer( {
          is: 'observing-test',

          ready: function(){
            console.log("Ready!");

            Polymer.dom( this.$.c ).observeNodes( function( info ) {
              console.log("CHANGED!", info );
            });
          },

          attached: function(){
            console.log("Attached!");
            // GLOBAL, so that we can play we it in the console
            OT = this;
          }

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

请记住,复合DOM是本地DOM的结果,解析了<content>个标签 所以,为了&#34;添加&#34;使用<content>替换select元素代替的元素,您需要向轻量级DOM添加符合<content>选择的元素。
例如,如果您的页面包含:

<observing-test>
  <p>Some content</p>
  <p class="line">Moved line 1</p>
  <p class="line">Moved line 2</p>
  <hr>
  <p class="line">Moved line 3</p>
</observing-test>

如果您随后创建了一个元素:

p = document.createElement('p')
p.appendChild(   document.createTextNode('text')   )
p.className = 'line'

并将其添加到light DOM:

Polymer.dom( OT ).appendChild( p )

<content>元素上的观察者被触发。 请注意,必须预先分配该类。如果你这样做:

p = document.createElement('p')
p.appendChild(   document.createTextNode('text')   )

然后你追加孩子:

Polymer.dom( OT ).appendChild( p )

只有然后才能将正确的类添加到元素中:

p.className = 'line'

回调没有被触发。

原来的问题并没有真正地工作&#34;因为过滤器是基于ID的。因此,只有一个元素匹配 - 因此被<content>选中。

相关问题