2015-09-28 76 views
4

在我的组件中,我想重复使用组件的光源提供的模板项目列表。例如:重复light dom元素

<template is="dom-repeat" items="{{items}}"> 
 
    <content select="#itemTemplate"></content> 
 
</template>

然而,似乎只有聚合物插入光DOM元素#itemTemplate而不是正好一个时间多次。有没有其他方法可以重复轻量级元素?

+0

总之,没有。不幸的是,分布式内容只能根据影子规格选择一次。 – zerodevx

+0

感谢您的信息! –

+0

还有其他方法可以达到这个效果 - 请参阅'iron-list',它使用了'Templatizer'。我真的很想知道我们如何实现一个使用''内部''iron-list''的元素 –

回答

0

您可以将您的内容包含在单独的元素中并使用它。

<template is="dom-repeat" items={{items}}"> 
    <child-element item=[[item]]></child-element> 
</template> 
+1

谢谢,但我想要实现的是允许用户使用light dom自定义项目列表,而不是使用固定项目组件。 这是一种由光芒动态模板。 –

2

我创建了一个简单的原型,它可以让你指定光DOM模板的重复次数。

由于内容位于light DOM中,因此您可以像平常一样从外部对其进行设计。而且模板内部的数据绑定也适用,因为我已经实现了Templatizer中的_forwardParentProp_forwardParentPath方法。

要知道,我有实施的实例特定的属性,这样可以让每行特定的变量,如indexitem。当然,这可以完成,但需要更多的工作。

查看原型:JSBin

OK,让我们进入细节:

test-element与数据绑定到两个input元素一起的用法相当简单:

<template is="dom-bind"> 
    Number of repeats: <input type="text" value="{{repeats::input}}" /> <br /> 
    Custom message: <input type="text" value="{{customMessage::input}}" /> 

    <test-element repeats="{{repeats}}"> 
     <template> 
      <h1>Title!</h1> 

      <p> 
       Custom message: <em>[[customMessage]]</em> 
      </p> 
     </template> 
    </test-element> 
</template> 

通知的dom-bind,这是需要建立一个数据绑定范围。

对于test-element,整个源代码如下所示:

<dom-module id="test-element"> 
    <template> 
     <style> 
     :host { 
      display: block; 
     } 
     </style> 

      <content></content> 
    </template> 

    <script> 
     Polymer({ 

      is: 'test-element', 

      behaviors: [ 
       Polymer.Templatizer, 
      ], 

      properties: { 
       repeats: { 
        type: Number, 
        value: 3, 
        notify: true, 
       }, 
      }, 

      observers: [ 
       '_repeatsChanged(repeats)', 
      ], 

      _repeatsChanged: function(repeats) { 
       // First time only: initialize template 
       if (this.template === undefined) { 
        this.template = Polymer.dom(this).querySelector('template'); 
        this.templatize(this.template); 
       } 

       // Remove previously stamped children 
       while (Polymer.dom(this).firstChild) { 
        Polymer.dom(this).removeChild(Polymer.dom(this).firstChild); 
       } 

       // Stamp new ones 
       this.stamped = new Array(repeats); 

       var inst; 
       for (var i = 0; i < repeats; i++) { 
        inst = this.stamp(null); 
        this.stamped[i] = inst.root.querySelector('*'); 
        Polymer.dom(this).appendChild(inst.root); 
       } 
      }, 

      // Copied from iron-list 
      _forwardParentProp: function(prop, value) { 
       if (this.stamped) { 
        this.stamped.forEach(function(item) { 
         item._templateInstance[prop] = value; 
        }, this); 
       } 
      }, 

      // Copied from iron-list 
      _forwardParentPath: function(path, value) { 
       if (this.stamped) { 
        this.stamped.forEach(function(item) { 
         item._templateInstance.notifyPath(path, value, true); 
        }, this); 
       } 
      }, 

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

只有一个属性,repeats,指定加盖实例的数量。默认值是3。为了适应物业价值的变化,已经创建了一个observer。这也是冲压发生的地方:

_repeatsChanged: function(repeats) { 
    // First time only: initialize template 
    if (this.template === undefined) { 
     this.template = Polymer.dom(this).querySelector('template'); 
     this.templatize(this.template); 
    } 

    // Remove previously stamped children 
    while (Polymer.dom(this).firstChild) { 
     Polymer.dom(this).removeChild(Polymer.dom(this).firstChild); 
    } 

    // Stamp new ones 
    this.stamped = new Array(repeats); 

    var inst; 
    for (var i = 0; i < repeats; i++) { 
     inst = this.stamp(null); 
     this.stamped[i] = inst.root.querySelector('*'); 
     Polymer.dom(this).appendChild(inst.root); 
    } 
}, 
  • 首先(且仅一次),模板从光DOM读取和 的templatize方法被调用。此方法初始化 Templatize行为。其次,所有之前加盖的孩子都被删除(以便元素不会无限制地建立起来)。
  • 第三,根据当前值 repeats加盖新孩子。所有加盖的实例都保存到this.stamped,其中 是外部数据绑定工作所必需的。

    // Copied from iron-list 
    _forwardParentProp: function(prop, value) { 
         if (this.stamped) { 
           this.stamped.forEach(function(item) { 
             item._templateInstance[prop] = value; 
           }, this); 
         } 
    }, 
    
    // Copied from iron-list 
    _forwardParentPath: function(path, value) { 
         if (this.stamped) { 
           this.stamped.forEach(function(item) { 
             item._templateInstance.notifyPath(path, value, true); 
           }, this); 
         } 
    }, 
    

    iron-list采取两种方法:

最后但并非最不重要的,Templatizer行为是通过两种方法(和两个都没有实现)来实现。他们遍历盖章的孩子并传播属性更改和路径通知。