是否有将jsViews / jsRender与Web组件一起用作模板引擎的用例?

问题描述

我正在编写一些Web组件,我想将jsViews $ .link功能用作我的模板引擎。我已经可以使用$ .render替换shadowRoot克隆内容的.innerHTML,但是我只能通过以下方式使用$ .link。似乎“肮脏”,不得不添加一个额外的div来链接。有一个更好的方法吗?这里有性能问题吗?:

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选择器),HTML元素是包装呈现的数据链接内容的容器元素。它不能直接是文档片段(影子根),因此您需要提供wrapper元素(并可选地还插入一个style元素),例如通过以下代码:

// 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);