为什么会失败
对,文档renderAsFragment
有点混乱;上面写着:
将 Soy 模板呈现为单个节点或文档片段。如果呈现的 HTML 字符串表示单个节点,则返回该节点
但是,(简化的)实现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>
?
这是因为,在内部,在决定它是否应该返回包装器(一般情况)或唯一的孩子(如果呈现的 HTML 仅代表一个节点)之前,safeHtmlToNode
放置safeHtml
在一个临时的。再次简化,代码为:div
div
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
,但这仅在您的表有一行时才有效,因为它替换了内容,并且不附加子节点。
推荐的方法
所以通常,我们在模板中执行 for 循环:
{template .myTable}
<table>
{foreach $person in $data.persons}
<tr><td>Hello {$person.name}</td></tr>
{/foreach}
</table>
{/template}
当然,我们可以将您拥有的简单模板保留在一行中,并将call
其保留在较大的模板中。