是否有将 jsViews/jsRender 与 Web 组件一起用作模板引擎的用例?
Are there any use cases of using jsViews/jsRender with web components as the templating engine?
我正在编写一些 Web 组件,我想使用 jsViews $.link 功能作为我的模板引擎。我已经能够使用 $.render 替换 shadowRoot 克隆内容的 .innerHTML 但我只能通过以下方式使用 $.link 。只是看起来“脏”得额外添加一个 div 到 link 来。有一个更好的方法吗?这里有任何性能问题吗?:
const template = document.createElement('template');
template.innerHTML = `<div id="todo-item-tmpl"></div>`;
class TodoItem extends HTMLElement {
constructor() {
this._tmpl = $.templates('#todoItems');
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
this._todoTmpl = this._shadowRoot.querySelector('#todo-item-tmpl');
this._tmpl.link(this._todoTmpl, this._myDataObj);
}
}
这是可能的方法,如您的示例的修改版本所示:https://jsfiddle.net/BorisMoore/z9wnyh5q/。
不是将模板定义为脚本元素的内容,而是使用标记字符串定义它们 - 以保留 Web 组件本身的 HTML 标记。
<html>
<head>...</head>
<body>
<to-do-app></to-do-app>
</body>
</html>
项目模板可以是全局定义的命名模板,
$.templates("todoItemTmpl", todoItemTmpl} // markup string for item template
或者可以作为资源作用于主模板,(https://www.jsviews.com/#d.templates@tmpl-resources),以获得更好的封装:
this._tmpl = $.templates({
markup: todoappTmpl, // markup string
templates: {todoItemTmpl: todoItemTmpl} // markup string for item template
});
对 this._tmpl.link(this._wrapper, this._todos, this);
(https://www.jsviews.com/#jsvtmpllink) 的调用需要将 HTML 元素(或 jQuery 选择器)作为第一个参数,它是包装呈现的容器元素数据链接的内容。它不能直接是文档片段(影子根),因此您需要提供包装器元素(并且还可以选择插入样式元素),例如通过以下代码:
// Create a wrapper element
this._wrapper = document.createElement('span');
// and a style element...
this._style = document.createElement('style');
this._style.textContent = todoappStyle; // Stylesheet markup
// Both inserted under the shadow root
this._shadowRoot = this.attachShadow({ mode: "open" });
this._shadowRoot.append(this._style, this._wrapper);
// Render and data-link
this._tmpl.link(this._wrapper, this._todos, this);
我正在编写一些 Web 组件,我想使用 jsViews $.link 功能作为我的模板引擎。我已经能够使用 $.render 替换 shadowRoot 克隆内容的 .innerHTML 但我只能通过以下方式使用 $.link 。只是看起来“脏”得额外添加一个 div 到 link 来。有一个更好的方法吗?这里有任何性能问题吗?:
const template = document.createElement('template');
template.innerHTML = `<div id="todo-item-tmpl"></div>`;
class TodoItem extends HTMLElement {
constructor() {
this._tmpl = $.templates('#todoItems');
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
this._todoTmpl = this._shadowRoot.querySelector('#todo-item-tmpl');
this._tmpl.link(this._todoTmpl, this._myDataObj);
}
}
这是可能的方法,如您的示例的修改版本所示:https://jsfiddle.net/BorisMoore/z9wnyh5q/。
不是将模板定义为脚本元素的内容,而是使用标记字符串定义它们 - 以保留 Web 组件本身的 HTML 标记。
<html>
<head>...</head>
<body>
<to-do-app></to-do-app>
</body>
</html>
项目模板可以是全局定义的命名模板,
$.templates("todoItemTmpl", todoItemTmpl} // markup string for item template
或者可以作为资源作用于主模板,(https://www.jsviews.com/#d.templates@tmpl-resources),以获得更好的封装:
this._tmpl = $.templates({
markup: todoappTmpl, // markup string
templates: {todoItemTmpl: todoItemTmpl} // markup string for item template
});
对 this._tmpl.link(this._wrapper, this._todos, this);
(https://www.jsviews.com/#jsvtmpllink) 的调用需要将 HTML 元素(或 jQuery 选择器)作为第一个参数,它是包装呈现的容器元素数据链接的内容。它不能直接是文档片段(影子根),因此您需要提供包装器元素(并且还可以选择插入样式元素),例如通过以下代码:
// Create a wrapper element
this._wrapper = document.createElement('span');
// and a style element...
this._style = document.createElement('style');
this._style.textContent = todoappStyle; // Stylesheet markup
// Both inserted under the shadow root
this._shadowRoot = this.attachShadow({ mode: "open" });
this._shadowRoot.append(this._style, this._wrapper);
// Render and data-link
this._tmpl.link(this._wrapper, this._todos, this);