如何使用 soy 模板渲染 tr?
How can I render a tr with soy templates?
我有这个大豆模板
{template .myRowTemplate}
<tr><td>Hello</td></tr>
{/template}
我想做类似
的事情
var myTable = goog.dom.createElement("table");
goog.dom.appendChild(myTable, goog.soy.renderAsFragment(mytemplates.myRowTemplate));
goog.dom.appendChild(myTable, goog.soy.renderAsFragment(mytemplates.myRowTemplate));
但这会导致
Uncaught goog.asserts.AssertionError
Assertion failed: This template starts with a <tr>,
which cannot be a child of a <div>, as required by soy internals.
Consider using goog.soy.renderElement instead.
Template output: <tr><td>Hello</td></tr>
最好的方法是什么?
为什么会失败
对了,renderAsFragment
的文档有点乱;上面写着:
Renders a Soy template into a single node or a document fragment. If the rendered HTML string represents a single node, then that node is returned
但是,renderAsFragment
的(简化)实现是:
var output = template(opt_templateData);
var html = goog.soy.ensureTemplateOutputHtml_(output);
goog.soy.assertFirstTagValid_(html); // This is your failure
var safeHtml = output.toSafeHtml();
return dom.safeHtmlToNode(safeHtml);
那么为什么闭包作者断言第一个标签不是<tr>
?
这是因为,在内部,safeHtmlToNode
将 safeHtml
放置在临时 div
中,然后再决定是否应该 return div
包装器(一般情况) 或独生子(如果呈现的 HTML 仅代表一个节点)。再次简化,safeHtmlToNode
的代码为:
var tempDiv = goog.dom.createElement_(doc, goog.dom.TagName.DIV);
goog.dom.safe.setInnerHtml(tempDiv, html);
if (tempDiv.childNodes.length == 1) {
return tempDiv.removeChild(tempDiv.firstChild);
} else {
var fragment = doc.createDocumentFragment();
while (tempDiv.firstChild) {
fragment.appendChild(tempDiv.firstChild);
}
return fragment;
}
renderAsElement 也不起作用
我不确定你要的片段是什么,但不幸的是 goog.soy.renderAsElement()
的行为是一样的,因为它也使用临时 div
来呈现 DOM。
renderElement 不能循环
错误消息提示 goog.soy.renderElement
,但只有当您的 table 有一行时才有效,因为它会替换内容,并且不会附加子节点。
推荐方法
所以通常,我们在模板中做 for 循环:
{template .myTable}
<table>
{foreach $person in $data.persons}
<tr><td>Hello {$person.name}</td></tr>
{/foreach}
</table>
{/template}
当然,我们可以将您的简单模板保留一行,call
它来自较大的模板。
我有这个大豆模板
{template .myRowTemplate}
<tr><td>Hello</td></tr>
{/template}
我想做类似
的事情var myTable = goog.dom.createElement("table");
goog.dom.appendChild(myTable, goog.soy.renderAsFragment(mytemplates.myRowTemplate));
goog.dom.appendChild(myTable, goog.soy.renderAsFragment(mytemplates.myRowTemplate));
但这会导致
Uncaught goog.asserts.AssertionError
Assertion failed: This template starts with a <tr>,
which cannot be a child of a <div>, as required by soy internals.
Consider using goog.soy.renderElement instead.
Template output: <tr><td>Hello</td></tr>
最好的方法是什么?
为什么会失败
对了,renderAsFragment
的文档有点乱;上面写着:
Renders a Soy template into a single node or a document fragment. If the rendered HTML string represents a single node, then that node is returned
但是,renderAsFragment
的(简化)实现是:
var output = template(opt_templateData);
var html = goog.soy.ensureTemplateOutputHtml_(output);
goog.soy.assertFirstTagValid_(html); // This is your failure
var safeHtml = output.toSafeHtml();
return dom.safeHtmlToNode(safeHtml);
那么为什么闭包作者断言第一个标签不是<tr>
?
这是因为,在内部,safeHtmlToNode
将 safeHtml
放置在临时 div
中,然后再决定是否应该 return div
包装器(一般情况) 或独生子(如果呈现的 HTML 仅代表一个节点)。再次简化,safeHtmlToNode
的代码为:
var tempDiv = goog.dom.createElement_(doc, goog.dom.TagName.DIV);
goog.dom.safe.setInnerHtml(tempDiv, html);
if (tempDiv.childNodes.length == 1) {
return tempDiv.removeChild(tempDiv.firstChild);
} else {
var fragment = doc.createDocumentFragment();
while (tempDiv.firstChild) {
fragment.appendChild(tempDiv.firstChild);
}
return fragment;
}
renderAsElement 也不起作用
我不确定你要的片段是什么,但不幸的是 goog.soy.renderAsElement()
的行为是一样的,因为它也使用临时 div
来呈现 DOM。
renderElement 不能循环
错误消息提示 goog.soy.renderElement
,但只有当您的 table 有一行时才有效,因为它会替换内容,并且不会附加子节点。
推荐方法
所以通常,我们在模板中做 for 循环:
{template .myTable}
<table>
{foreach $person in $data.persons}
<tr><td>Hello {$person.name}</td></tr>
{/foreach}
</table>
{/template}
当然,我们可以将您的简单模板保留一行,call
它来自较大的模板。