我需要为我正在处理的enyo项目创建一个数据表,它最终将显示Ajax调用的结果。 This(从ryanjduffy here公然被盗)似乎是一个很好的起点,但当我尝试从按钮事件(而不是在构造函数中)调用setData()时,我{{3我收到以下错误:
InvalidCharacterError: String contains an invalid character @ http://enyojs.com/enyo-2.1/enyo/source/dom/Control.js:681
我查看了Control.js代码,似乎它尝试创建一个新节点,但this.tag
属性设置为null
并且事情中断了。
我觉得我错过了一些非常简单的东西,但我还是看不到问题......
有人能告诉我我做错了吗?
谢谢!
编辑1:
显然不需要调用render()。带有render()的here已注释掉。一切看起来都很棒。但是,如果我尝试从Here is the original working version删除render(),则转发器会开始在表格上方创建div
而不是tr td
在表格内......
编辑2:
基本上,据我所知,表格中的Repeater会在表格渲染后丢失它的父级(或类似的东西)。结果是Repeater将开始在原始表之外呈现其新项目,并且因为没有td
的{{1}}标记没有意义,它只会呈现table
。
我提出的解决方案是给Repeater本身一个div
标签,这样它的孩子总能在正确的位置结束。这增加了每次都需要重新创建标题行的挑战,但这并不是什么大不了的事。 version that requires a button click如果有人有兴趣的话。
答案 0 :(得分:2)
我确定你不再寻找解决方案但是因为我在帖子中提到过,我想我会让你知道我发现了什么。简而言之,我的代码不应该有效,但由于浏览器是宽容的,它确实......有点像。
当代码在创建时运行时,它会呈现如下内容:
<table>
<tr> <!-- header row --> </tr>
<div> <!-- repeater tag -->
<tr> <!-- repeater row --> </tr>
</div>
</table>
浏览器看着它然后说,&#34;嘿,假! <div>
&#34;中没有<table>
s然后把它踢出去,但留下<tr>
s。
在您的示例中,由于您要延迟行的渲染,Enyo呈现:
<table>
<tr> <!-- header row --> </tr>
<div></div>
</table>
浏览器会弹出<div>
,然后你会留下一张空桌子。稍后设置数据时,这些行将呈现为div。不幸的是,由于您正在呈现<tr>
和<td>
,因此这些内容在表格之外无效,因此您只需获取文字。
我找到了几个解决方案。最简单的方法是将Repeater的tag
设置为TBODY,允许在表中使用。稍微复杂一点的解决方案是使DataTable继承自Repeater并将标题行设置为chrome,以便在更新数据时不会删除它们。
enyo.kind({
name:"DataTable",
tag: "table",
kind: "Repeater",
published:{
map:0,
data:0
},
handlers: {
onSetupItem: "setupItem"
},
components:[
{name:"row", kind:"DataRow"}
],
create:function() {
this.inherited(arguments);
this.mapChanged = this.dataChanged = enyo.bind(this, "refresh");
this.refresh();
},
refresh:function() {
if(this.map && this.data) {
this.buildHeader();
this.setCount(this.data.length);
}
},
buildHeader:function() {
if(this.$.header) {
this.$.header.destroyClientControls();
} else {
this.createComponent({name:"header", tag:"tr", isChrome: true});
}
for(var i=0;i<this.map.length;i++) {
this.$.header.createComponent({content:this.map[i].header, tag:"th"});
}
this.$.header.render();
},
setupItem:function(source, event) {
for(var i=0;i<this.map.length;i++) {
event.item.$.row.createComponent({content:this.data[event.index][this.map[i].field]});
}
event.item.render();
return true;
}
});