不能多次使用 Web 组件
Cannot use Web Components more than once
我是 vanilla 的新手 javascript 因为我只有 reactjs 方面的经验。我试图显示我在两个地方创建的 Web 组件。但它只显示一次。这可能是什么问题?
我的网络组件
class MyComponent extends HTMLElement {
constructor() {
// always call super() first
super();
console.log('constructed!');
}
connectedCallback() {
// console.log(this.getAttribute("filter"));
this.innerHTML = `
<html>
<div id="templates" class="template_style">
<template id="book-template">
<li><span class="title"></span> — <span class="author"></span></li>
</template>
<ul id="books"></ul>
</div>
</html>
`;
}
}
customElements.define('my-component', MyComponent);
用于使用数据填充 Web 组件的 JS 代码
import JsonObj from './debts.js';
const books = JsonObj;
function appendBooks() {
const booksList = document.getElementById('books');
const fragment = document.getElementById('book-template');
// Clear out the content from the ul
booksList.innerHTML = '';
console.log(books);
// Loop over the books and modify the given template
books.debts.forEach(book => {
// Create an instance of the template content
const instance = document.importNode(fragment.content, true);
// Add relevant content to the template
instance.querySelector('.title').innerHTML = book.bank;
instance.querySelector('.author').innerHTML = book.category;
// Append the instance ot the DOM
booksList.appendChild(instance);
});
}
document.getElementById('templates').addEventListener('change', (event) => appendBooks());
appendBooks('book-template');
HTML 我使用上述组件的代码
<div>
<div class="sub_container">
<label>Users in Debt</label>
<input placeholder="Search by user name" class="input_style">
<my-component filter="userdebt"></my-component>
</div>
<div class="sub_container">
<label>Debts</label>
<input placeholder="Search by debt description" class="input_style">
<my-component filter="debt"></my-component>
</div>
</div>
因此,正如在 html 代码中看到的那样,我在两个地方使用了 </my-component>
,但我只能看到第一个实例。我在我的组件中使用了 console.log 内部构造函数,我可以看到它调用了 2 次。但在视图中我只能看到第一个实例。我该如何解决这个问题?
我已经在 codepen 中重复了你的代码,它的工作如你所愿。生成两个组件。如果有,您应该检查其他地方是否有错误。
并且不要因为重复而在组件中使用静态 ID。 HTML标签也不需要使用。
您应该将 id
添加到 web-component 本身,以便您可以使用 parent 的 id
查询 child 节点包含在其中
在您的代码中,当使用 web-component 的 child 的 id
查询时,它为您获取了第一个,因为您有重复的 ID,在我的代码中,我给了每个<my-component>
标记一个唯一的 id
这样我就只能查询它的 child:
class MyComponent extends HTMLElement {
constructor() {
// always call super() first
super();
console.log('constructed!');
}
connectedCallback() {
// console.log(this.getAttribute("filter"));
this.innerHTML = `
<div id="templates" class="template_style">
<template id="book-template">
<li><span class="title"></span> — <span class="author"></span></li>
</template>
<ul id="books"></ul>
</div>
`;
}
}
customElements.define('my-component', MyComponent);
const books = [{bank : "foo", category: "bar"}];
function appendBooks(id) {
const comp = document.getElementById(id);
//query for the child of the parent web-component
const booksList = comp.querySelector('#books');
const fragment = comp.querySelector('#book-template');
// Clear out the content from the ul
booksList.innerHTML = '';
// Loop over the books and modify the given template
books.forEach(book => {
// Create an instance of the template content
const instance = document.importNode(fragment.content, true);
// Add relevant content to the template
instance.querySelector('.title').innerHTML = book.bank;
instance.querySelector('.author').innerHTML = book.category;
// Append the instance ot the DOM
booksList.appendChild(instance);
});
}
function addChangeListener(id){
document.getElementById(id)
.querySelector('#templates')
.addEventListener('change', (event) => appendBooks());
}
appendBooks('comp1'); //for componenent having id = comp1
appendBooks('comp2'); //for componenent having id = comp2
addChangeListener('comp1')
addChangeListener('comp2')
<div>
<div class="sub_container">
<label>Users in Debt</label>
<input placeholder="Search by user name" class="input_style">
<my-component id="comp1" filter="userdebt"></my-component>
</div>
<div class="sub_container">
<label>Debts</label>
<input placeholder="Search by debt description" class="input_style">
<my-component id="comp2" filter="debt"></my-component>
</div>
</div>
我是 vanilla 的新手 javascript 因为我只有 reactjs 方面的经验。我试图显示我在两个地方创建的 Web 组件。但它只显示一次。这可能是什么问题?
我的网络组件
class MyComponent extends HTMLElement {
constructor() {
// always call super() first
super();
console.log('constructed!');
}
connectedCallback() {
// console.log(this.getAttribute("filter"));
this.innerHTML = `
<html>
<div id="templates" class="template_style">
<template id="book-template">
<li><span class="title"></span> — <span class="author"></span></li>
</template>
<ul id="books"></ul>
</div>
</html>
`;
}
}
customElements.define('my-component', MyComponent);
用于使用数据填充 Web 组件的 JS 代码
import JsonObj from './debts.js';
const books = JsonObj;
function appendBooks() {
const booksList = document.getElementById('books');
const fragment = document.getElementById('book-template');
// Clear out the content from the ul
booksList.innerHTML = '';
console.log(books);
// Loop over the books and modify the given template
books.debts.forEach(book => {
// Create an instance of the template content
const instance = document.importNode(fragment.content, true);
// Add relevant content to the template
instance.querySelector('.title').innerHTML = book.bank;
instance.querySelector('.author').innerHTML = book.category;
// Append the instance ot the DOM
booksList.appendChild(instance);
});
}
document.getElementById('templates').addEventListener('change', (event) => appendBooks());
appendBooks('book-template');
HTML 我使用上述组件的代码
<div>
<div class="sub_container">
<label>Users in Debt</label>
<input placeholder="Search by user name" class="input_style">
<my-component filter="userdebt"></my-component>
</div>
<div class="sub_container">
<label>Debts</label>
<input placeholder="Search by debt description" class="input_style">
<my-component filter="debt"></my-component>
</div>
</div>
因此,正如在 html 代码中看到的那样,我在两个地方使用了 </my-component>
,但我只能看到第一个实例。我在我的组件中使用了 console.log 内部构造函数,我可以看到它调用了 2 次。但在视图中我只能看到第一个实例。我该如何解决这个问题?
我已经在 codepen 中重复了你的代码,它的工作如你所愿。生成两个组件。如果有,您应该检查其他地方是否有错误。 并且不要因为重复而在组件中使用静态 ID。 HTML标签也不需要使用。
您应该将 id
添加到 web-component 本身,以便您可以使用 parent 的 id
查询 child 节点包含在其中
在您的代码中,当使用 web-component 的 child 的 id
查询时,它为您获取了第一个,因为您有重复的 ID,在我的代码中,我给了每个<my-component>
标记一个唯一的 id
这样我就只能查询它的 child:
class MyComponent extends HTMLElement {
constructor() {
// always call super() first
super();
console.log('constructed!');
}
connectedCallback() {
// console.log(this.getAttribute("filter"));
this.innerHTML = `
<div id="templates" class="template_style">
<template id="book-template">
<li><span class="title"></span> — <span class="author"></span></li>
</template>
<ul id="books"></ul>
</div>
`;
}
}
customElements.define('my-component', MyComponent);
const books = [{bank : "foo", category: "bar"}];
function appendBooks(id) {
const comp = document.getElementById(id);
//query for the child of the parent web-component
const booksList = comp.querySelector('#books');
const fragment = comp.querySelector('#book-template');
// Clear out the content from the ul
booksList.innerHTML = '';
// Loop over the books and modify the given template
books.forEach(book => {
// Create an instance of the template content
const instance = document.importNode(fragment.content, true);
// Add relevant content to the template
instance.querySelector('.title').innerHTML = book.bank;
instance.querySelector('.author').innerHTML = book.category;
// Append the instance ot the DOM
booksList.appendChild(instance);
});
}
function addChangeListener(id){
document.getElementById(id)
.querySelector('#templates')
.addEventListener('change', (event) => appendBooks());
}
appendBooks('comp1'); //for componenent having id = comp1
appendBooks('comp2'); //for componenent having id = comp2
addChangeListener('comp1')
addChangeListener('comp2')
<div>
<div class="sub_container">
<label>Users in Debt</label>
<input placeholder="Search by user name" class="input_style">
<my-component id="comp1" filter="userdebt"></my-component>
</div>
<div class="sub_container">
<label>Debts</label>
<input placeholder="Search by debt description" class="input_style">
<my-component id="comp2" filter="debt"></my-component>
</div>
</div>