简单聚合物 1.0 数据 table
Simple Polymer 1.0 data table
我正在尝试创建一个简单的 Polymer 组件,它从数据数组中呈现 table。所述组件的预期用途示例如下:
<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
。
有没有办法在不定义计算绑定的情况下解决这个问题?否则单元格值的自定义格式是不可能的。
我认为您遇到的问题之一是 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'},
];
},
});
第二个问题是在 <template is="dom-bind">
中使用 <template>
,这就是它停止工作的原因。不确定你为什么要这样做。
当你说本地 http 服务器是如何配置的?。通常需要确保导入引用正确的位置然后 hrefs 像 ../polymer/polymer.html
Polymer 提供的工具(例如 polyserve 和 web-component-tester) all 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>
然而,您的 <my-table>
元素不使用 <content>
标签,该标签将拉入该内容。我不确定它是否必要 - 我认为您的顶级元素模板 <my-table>
已经包含列。
你这里的构造很有趣!
- 我不知道为什么它在 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>
问题 #2(当组件被 dom-bind
包装时数据绑定不起作用)的解决方案如下。您需要实现以下方法,如 Templatizer 行为所定义:
_forwardParentProp: function(prop, value)
_forwardParentPath: function(path, value)
_showHideChildren: function(shouldHide)
您还需要设置 _instanceProps
以定义任何与实例相关的属性。
我正在尝试创建一个简单的 Polymer 组件,它从数据数组中呈现 table。所述组件的预期用途示例如下:
<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
。
有没有办法在不定义计算绑定的情况下解决这个问题?否则单元格值的自定义格式是不可能的。
我认为您遇到的问题之一是 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'},
];
},
});
第二个问题是在 <template is="dom-bind">
中使用 <template>
,这就是它停止工作的原因。不确定你为什么要这样做。
当你说本地 http 服务器是如何配置的?。通常需要确保导入引用正确的位置然后 hrefs 像 ../polymer/polymer.html
Polymer 提供的工具(例如 polyserve 和 web-component-tester) all 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>
然而,您的 <my-table>
元素不使用 <content>
标签,该标签将拉入该内容。我不确定它是否必要 - 我认为您的顶级元素模板 <my-table>
已经包含列。
你这里的构造很有趣!
- 我不知道为什么它在 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>
问题 #2(当组件被 dom-bind
包装时数据绑定不起作用)的解决方案如下。您需要实现以下方法,如 Templatizer 行为所定义:
_forwardParentProp: function(prop, value)
_forwardParentPath: function(path, value)
_showHideChildren: function(shouldHide)
您还需要设置 _instanceProps
以定义任何与实例相关的属性。