【问题标题】:Simple Polymer 1.0 data tableSimple Polymer 1.0 数据表
【发布时间】:2016-02-11 15:21:20
【问题描述】:

我正在尝试创建一个简单的 Polymer 组件,该组件从数据数组中呈现一个表。所述组件的预期用途示例如下:

<my-table data="{{someArray}}">
  <my-column header="Id"><template>{{item.id}}</template></my-column>
  <my-column header="Name"><template>{{item.name}}</template></my-column>
</my-table>

渲染应该是这样的:

然而,在创建一个半工作原型时,事情变得复杂了。原型可以在这里找到:http://jsbin.com/sirutusupu/edit?html,console,output免责声明:除非您下载它并通过本地http-server 运行它,否则它不起作用。

我的第一个问题:为什么原型只能通过本地http-server工作?

我的第二个问题:在本地运行时,当我用dom-bind 包装自定义元素时,它也停止工作。本地代码(也不起作用):

<template is="dom-bind">
  <my-table>
    <my-column header="Id"><template>{{item.id}}</template></my-column>
    <my-column header="Name"><template>{{item.name}}</template></my-column>
  </my-table>
</template>

我的第三个问题:使用函数格式化输出不起作用。考虑这个扩展示例:

<script>
  function concat(a, b) {
    return a + "-" + b;
  }
</script>
<my-table>
  <my-column header="Id"><template>{{item.id}}</template></my-column>
  <my-column header="Name"><template>{{item.name}}</template></my-column>
  <my-column header="Computed"><template>{{concat(item.id, item.name)}}</template></my-column>
</my-table>

产生的错误是polymer.html:1660 [undefined::_annotatedComputationEffect]: compute method 'concat' not defined

有没有办法在不定义计算绑定的情况下解决这个问题?否则无法自定义单元格值的格式。

【问题讨论】:

    标签: javascript html templates polymer polymer-1.0


    【解决方案1】:

    你在这里有一个有趣的结构!

    • 我不知道为什么它在 jsbin 中对你不起作用,它可能有 和rawgit有关,我用polygit代替。
    • 如果您将计算功能放在 模板化后列的ctor.prototype
    • dom.bind 会弄乱内部template,我会避免 它。

    这个似乎有效:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title>My table</title>      
      <base href="//polygit.org/components/">
      <link rel="import" href="polymer/polymer.html" >     
    </head>
    <body>
      <my-table>
        <my-column header="Id"><template>{{item.id}}</template></my-column>
        <my-column header="Name"><template>{{item.name}}</template></my-column>
        <my-column header="Computed"><template>{{concat(item.id, item.name)}}</template>
      </my-table>
      
      <dom-module id="my-table">
        <template>
          <table border="1">
            <tr>
              <template is="dom-repeat" items="{{columns}}" as="column">
                <th>{{column.header}}</th>
              </template>
            </tr>
            <template is="dom-repeat" items="{{items}}" as="row">
              <tr>
                <template is="dom-repeat" items="{{columns}}" as="column">
                  <td>
                    <my-cell column="{{column}}" row="{{row}}"></my-cell>
                  </td>
                </template>
              </tr>
            </template>
          </table>
        </template>
      </dom-module>
      
      <script>
        Polymer({
          is: 'my-table',
          ready: function() {
            this.columns = Array.prototype.slice.call(Polymer.dom(this).querySelectorAll('my-column'));
            this.items = [
              {id: 1, name: 'John'},
              {id: 2, name: 'Jane'},
            ];
          }
        });
    
        Polymer({
          is: 'my-column',
          properties: {
            header: String
          },
          ready: function() {
            this.templatize(Polymer.dom(this).querySelector('template'));
            this.ctor.prototype.concat = function(id, name) {
              return name + '(' + id + ')';
            }
          },
          stampCell: function(row) {
            return this.stamp({item: row});
          },
          behaviors: [Polymer.Templatizer]
        });
    
        Polymer({
          is: 'my-cell',
          ready: function() {
            Polymer.dom(this).appendChild(this.column.stampCell(this.row).root);
          }
        });
      </script>    
    </body>
    </html>

    【讨论】:

    • 感谢您解决问题 #1 和 #3。您是否知道为什么#2 不起作用,即使在您的代码示例中也是如此?尝试将&lt;my-table&gt; 包装在&lt;template is="dom-bind"&gt;&lt;/template&gt; 中,数据绑定会以某种方式停止工作。我仍在寻找解决此问题的方法。到目前为止,没有成功...
    • 如果将表格包装在 dom-bind 中,则内部模板将成为 &lt;template is="dom-bind"&gt; 超结构的一部分,并且不能供列使用。
    • 真的没有办法了吗?
    • 可能有,但我得考虑一下。
    【解决方案2】:

    我认为您遇到的一个问题是columns 的定义。它在properties 对象之外

    应该是这样的

    Polymer({
      is: 'my-table',
      properties: {
        items: Array,
        columns: {
          type: Array,
          value: function(){return [];}
        }
    
      },
      ready: function() {
        this.columns = Polymer.dom(this).querySelectorAll('my-column');
    
        this.items = [
          {id: 1, name: 'John'},
          {id: 2, name: 'Jane'},
        ];
      },
    });
    

    第二个问题是在&lt;template is="dom-bind"&gt; 中使用&lt;template&gt;,这就是它停止工作的原因。不知道你为什么这样做。

    当您说本地 http-server 时,它是如何配置的?通常有必要确保导入引用正确的位置,然后具有像../polymer/polymer.html 这样的href Polymer 提供的工具(例如polyserve 和web-component-tester)所有map bower_components 都是特殊方式,因此您可以参考../ 样式的元素。您是在使用他们的本地 http 服务器之一还是您制作的东西?您可以使用其他 Web 服务器(如 apache 或 ngnix)来执行此操作,您只需意识到您需要将 url 映射更改为文件目录映射以便它工作。

    编辑

    在你的 jsbin 底部你可以这样做

      <my-table>
        <my-column header="Id"><template>{{item.id}}</template></my-column>
        <my-column header="Name"><template>{{item.name}}</template></my-column>
      </my-table>
    

    但是,您的 &lt;my-table&gt; 元素不使用 &lt;content&gt; 标记,这将拉入该内容。我不确定它是否必要 - 我认为您的 &lt;my-table&gt; 的顶级元素模板已经包含列。

    【讨论】:

    • 使用本地http-server时,代码与JSbin相同。甚至 polymer.html 也包含在 GitHub 中。不需要&lt;content&gt;,因为我不需要将 light DOM 复制到 shadow DOM。
    • 是第一点——然后我不知道你为什么不能使用它——你使用的是 jsbin 是不是你不一样。再说第二点。我说你不需要它,但我引用的代码在&lt;my-table&gt;&lt;/my-table&gt; 之间有东西,所以结果在哪里。在地板上,或者只是漂浮在你的顶级 html 中?
    【解决方案3】:

    问题#2(组件被dom-bind包裹时数据绑定不起作用)的解决方案如下。根据Templatizer 行为的定义,您需要实现以下方法:

    • _forwardParentProp: function(prop, value)
    • _forwardParentPath: function(path, value)
    • _showHideChildren: function(shouldHide)

    您还需要设置_instanceProps 来定义任何与实例相关的属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      相关资源
      最近更新 更多