【问题标题】:Append distributed child to <content> element in Polymer将分布式子元素附加到 Polymer 中的 <content> 元素
【发布时间】:2015-11-30 02:48:46
【问题描述】:

我有一个简单的 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 &lt;content&gt; 元素以便触发观察者?

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

所以问题:

  • 当观察本地 DOM 中的 &lt;content&gt; 元素时,如何从那里追加删除一个节点?基本上,我想在&lt;content&gt; 中添加一个额外的子元素,以便OT.getContentChildren('#top') 返回一个额外的元素

  • 观察时,我是否会收到直接对节点的其中一个子节点所做的更改的通知?孙子的修改不会冒泡,对吧?在定位 &lt;content&gt; 元素时,我实际上观察到什么?

【问题讨论】:

    标签: dom polymer shadow-dom


    【解决方案1】:
    • &lt;content&gt; 是一个 DOM 插入点(我不会尝试详细解释它是什么,Polymer's dev guide 比我做得更好)。基本上,与&lt;content&gt; 节点的select 查询匹配的组件的每个轻量级 DOM 子节点都将插入其中。

      因此,要在 &lt;content&gt; 节点中插入另一个子节点,您必须添加一个与它的 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 插入点,您不是直接插入另一个节点。我相信这就是您没有收到通知的原因。

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

    【讨论】:

      【解决方案2】:

      还发布了我自己的答案,这是文森特的(谢谢!)

      如果你有这样的元素:

          <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 的结果,&lt;content&gt; 标签已解析。
      因此,为了用select 将元素“添加”到代替&lt;content&gt; 元素的内容中,您需要将元素添加到与&lt;content&gt; 的选择相匹配的轻量DOM。
      例如,如果您的页面包含:

      <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 )
      

      &lt;content&gt; 元素上的观察者被触发。 请注意,您必须事先分配类。如果你这样做:

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

      然后你追加孩子:

      Polymer.dom( OT ).appendChild( p )
      

      只有然后你才能为元素添加正确的类:

      p.className = 'line'
      

      回调没有被触发。

      最初的问题并没有真正“起作用”,因为过滤器是基于 ID 的。因此,只有一个元素会匹配——因此会被&lt;content&gt; 选中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-19
        • 2015-06-22
        • 2021-11-27
        相关资源
        最近更新 更多