Javascript Web组件转换发生得太晚

Javascript Web组件转换发生得太晚,javascript,interpolation,web-component,Javascript,Interpolation,Web Component,在下面的(简化)代码中,第一个Tester实例使用预定义的模板,而第二个使用直接编码的模板。插值适用于第二个,因为html包含正确的html代码。在插值期间,第一个Tester实例仍然具有的innerHTML。如何更改代码概念以同时插入第一个示例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title&g

在下面的(简化)代码中,第一个Tester实例使用预定义的模板,而第二个使用直接编码的模板。插值适用于第二个,因为html包含正确的html代码。在插值期间,第一个Tester实例仍然具有的innerHTML。如何更改代码概念以同时插入第一个示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Web Components Demo</title>
</head>
<body>
    <div id="tc"></div>
    <div id="tc2"></div>
    <script>
        class TestComponent extends HTMLElement {
            constructor () {
                super();
                this.attachShadow({mode: "open"});
                this.shadowRoot.appendChild(this.createTemplate().content.cloneNode(true));
            }
            createTemplate () {
                const template = document.createElement("template");
                template.innerHTML = "<h1>{{title}}</h1><p>{{text}}</p>";
                return template;
            }
        }
        window.customElements.define("test-component", TestComponent);

        class Tester {
            constructor ({selector, stuff, template}) {
                this.selector = Array.from(document.querySelectorAll(selector));
                this.template = template || null;
                this.stuff = stuff;
                this.render();
                this.interpolate();
            }
            render () {
                this.selector.forEach(s => {if (this.template) s.innerHTML = this.template});
            }
            interpolate () {
                this.selector.forEach(s => {
                    for (let key in this.stuff) { 
                        const regex = new RegExp(`{{ *${key} *}}`, "g");       
                        s.innerHTML = s.innerHTML.replace(regex, this.stuff[key]);;
                    } 
                });
            }
        }

        new Tester ({
            selector: "#tc",
            stuff: {title: "Test Title", text: "Lorem ipsum dolor sit amet"},
            template: "<test-component>"
        });

        new Tester ({
            selector: "#tc2",
            stuff: {title: "Title that works", text: "Lorem ipsum dolor sit amet"},
            template: "<h1>{{title}}</h1><p>{{text}}</p>"
        })
    </script>
</body>
</html>

Web组件演示
类TestComponent扩展了HtmleElement{
构造函数(){
超级();
this.attachShadow({mode:“open”});
this.shadowRoot.appendChild(this.createTemplate().content.cloneNode(true));
}
createTemplate(){
const template=document.createElement(“模板”);
template.innerHTML=“{{title}}{{{text}}

”; 返回模板; } } 定义(“测试组件”,TestComponent); 类测试员{ 构造函数({selector,stuff,template}){ this.selector=Array.from(document.querySelectorAll(selector)); this.template=template | | null; this.stuff=东西; 这个。render(); 这个。插值(); } 渲染(){ this.selector.forEach(s=>{if(this.template)s.innerHTML=this.template}); } 插入(){ this.selector.forEach(s=>{ 对于(让我们输入这个.stuff){ const regex=new RegExp(`{*${key}*}}`,g”); s、 innerHTML=s.innerHTML.replace(regex,this.stuff[key]);; } }); } } 新测试仪({ 选择器:“#tc”, 材料:{标题:“测试标题”,文本:“Lorem ipsum dolor sit amet”}, 模板:“” }); 新测试仪({ 选择器:“#tc2”, 材料:{标题:“有效的标题”,文本:“Lorem ipsum dolor sit amet”}, 模板:“{title}}{{text}}

” })
您的主要问题是:

s.innerHTML = s.innerHTML.replace(regex, this.stuff[key]);
s
是外部DIV,而不是
内部html

constructor () {
    super() // returns 'this'
       .attachShadow({mode: "open"}) // returns shadowRoot
       .innerHTML = "<h1>{{title}}</h1><p>{{text}}</p>";
}
有效地销毁和重新创建每个密钥

因此,
constructor()
总是再次将默认模板设置为(元素)innerHTML:

控制台记录在第一个示例上运行的代码:

构造函数(){
超级();
this.attachShadow({mode:“open”});
this.shadowRoot.appendChild(this.createTemplate().content.cloneNode(true));
}
createTemplate(){
const template=document.createElement(“模板”);
template.innerHTML=“{{title}}{{{text}}

”; 返回模板; }
有点臃肿:您正在模板内创建HTML,然后克隆的模板内容(即:HTML)添加到空的shadowRoot innerHTML中

constructor () {
    super() // returns 'this'
       .attachShadow({mode: "open"}) // returns shadowRoot
       .innerHTML = "<h1>{{title}}</h1><p>{{text}}</p>";
}
构造函数(){
super()//返回“this”
.attachShadow({mode:“open”})//返回shadowRoot
.innerHTML=“{title}}{{text}}

”; }
仅当需要重新使用原始(模板)时,才需要克隆(模板)

解决方案:在元素内部移动{}解析

define(“测试组件”,类扩展HtmleElement{
构造函数(){
super().attachShadow({mode:“open”});
这个.setTemplate(`{{title}}{{text}}`);
}
setTemplate(html,数据={}){
this.shadowRoot.innerHTML=html;
解析(数据);
}
解析(数据){
让html=this.shadowRoot.innerHTML;
for(让我们输入数据){
const regex=new RegExp(`{${key}}}}`,g”);
html=html.replace(regex,data[key]);
}
this.shadowRoot.innerHTML=html;
}
});
一、解析({
标题:“测试标题”,
正文:“Lorem ipsum dolor sit amet”
})
两个.setTemplate({{title}}{{subtitle}}}){
标题:“测试二”,
副标题:“副标题”
})
设三=document.createElement('test-component');
解析({//在shadowDOM innerHTML中解析!
标题:“标题三”,
正文:“正文三”
})
document.body.append(三个)

如果我想访问HTML组件,我该怎么做?有没有办法从另一个对象解析组件?使用
模式:“open”
shadowDOM是。。。打开内容是
document.querySelector(…).shadowRoot.innerHTML