将 lit / lit-html TemplateResult 渲染为字符串
Render lit / lit-html TemplateResult as string
在lit/lit-html/lit-element中,标准组件是TemplateResult(通常是HTMLTemplateResult),创建方式如下:
function renderMe(msg) {
return html`<div>Hello ${msg}!</div>`;
}
当然,库的强大功能和效率在于后续调用将重用相同的 <div>
元素并且仅替换更改的片段。
然而,为了测试上面的 renderMe()
函数,能够将 return 值视为标准字符串会很有帮助,例如:
assert.equal(RENDER_AS_STRING(renderMe('kimiko')), '<div>Hello kimiko!</div>');
并在测试它如何呈现到浏览器本身之前修复函数中的任何错误。
是否有类似 RENDER_AS_STRING
的功能,无论是在 lit 本身还是在测试库中?我已经搜索过了,没有找到。
执行结果包含交替出现的html strings
和values
:
我们可以按相同的顺序组合它们:
function renderMe(msg) {
return html`<div>Hello ${msg}!</div>`;
}
const getRenderString = (data) => {
const {strings, values} = data;
const v = [...values, ''] // + last emtpty part
return strings.reduce((acc,s, i) => acc + s + v[i], '')
}
console.log(getRenderString(renderMe('SO')))
您可以在the playground
中测试
和recursive版本
import {html, css, LitElement} from 'lit';
function renderMe(msg) {
return html`<p>Hello ${msg}!</p>`;
}
function renderBlock(msg) {
return html`<div>${renderMe(msg)}</div>`;
}
const getRenderString = (data) => {
const {strings, values} = data;
const v = [...values, ''].map(e => typeof e === 'object' ? getRenderString(e) : e )
return strings.reduce((acc,s, i) => acc + s + v[i], '')
}
document.getElementById('output').textContent = getRenderString(renderBlock('SO'))
如果参数是字符串,@Daniil Loban 的答案很有效,但如果它们本身可能是 TemplateResults 或 TemplateResults 数组(规范都允许),则需要更复杂的答案:
export function template_as_string(data) {
const {strings, values} = data;
const value_list = [...values, '']; // + last empty part
let output = '';
for (let i = 0; i < strings.length; i++) {
let v = value_list[i];
if (v._$litType$ !== undefined) {
v = template_as_string(v); // embedded Template
} else if (v instanceof Array) {
// array of strings or templates.
let new_v = '';
for (const inner_v of [...v]) {
new_v += template_as_string(inner_v);
}
v = new_v;
}
output += strings[i] + v;
}
return output;
}
在lit/lit-html/lit-element中,标准组件是TemplateResult(通常是HTMLTemplateResult),创建方式如下:
function renderMe(msg) {
return html`<div>Hello ${msg}!</div>`;
}
当然,库的强大功能和效率在于后续调用将重用相同的 <div>
元素并且仅替换更改的片段。
然而,为了测试上面的 renderMe()
函数,能够将 return 值视为标准字符串会很有帮助,例如:
assert.equal(RENDER_AS_STRING(renderMe('kimiko')), '<div>Hello kimiko!</div>');
并在测试它如何呈现到浏览器本身之前修复函数中的任何错误。
是否有类似 RENDER_AS_STRING
的功能,无论是在 lit 本身还是在测试库中?我已经搜索过了,没有找到。
执行结果包含交替出现的html strings
和values
:
我们可以按相同的顺序组合它们:
function renderMe(msg) {
return html`<div>Hello ${msg}!</div>`;
}
const getRenderString = (data) => {
const {strings, values} = data;
const v = [...values, ''] // + last emtpty part
return strings.reduce((acc,s, i) => acc + s + v[i], '')
}
console.log(getRenderString(renderMe('SO')))
您可以在the playground
中测试和recursive版本
import {html, css, LitElement} from 'lit';
function renderMe(msg) {
return html`<p>Hello ${msg}!</p>`;
}
function renderBlock(msg) {
return html`<div>${renderMe(msg)}</div>`;
}
const getRenderString = (data) => {
const {strings, values} = data;
const v = [...values, ''].map(e => typeof e === 'object' ? getRenderString(e) : e )
return strings.reduce((acc,s, i) => acc + s + v[i], '')
}
document.getElementById('output').textContent = getRenderString(renderBlock('SO'))
如果参数是字符串,@Daniil Loban 的答案很有效,但如果它们本身可能是 TemplateResults 或 TemplateResults 数组(规范都允许),则需要更复杂的答案:
export function template_as_string(data) {
const {strings, values} = data;
const value_list = [...values, '']; // + last empty part
let output = '';
for (let i = 0; i < strings.length; i++) {
let v = value_list[i];
if (v._$litType$ !== undefined) {
v = template_as_string(v); // embedded Template
} else if (v instanceof Array) {
// array of strings or templates.
let new_v = '';
for (const inner_v of [...v]) {
new_v += template_as_string(inner_v);
}
v = new_v;
}
output += strings[i] + v;
}
return output;
}