gpt4 book ai didi

javascript - 使用 connectedCallback() 会破坏 Web 组件

转载 作者:行者123 更新时间:2023-11-30 13:57:47 24 4
gpt4 key购买 nike

我正在学习网络组件并正在构建一个动态列表以掌握它们。让它工作后,我读到最好使用 connectedCallback 方法附加影子根。但是,尝试这样做后,我遇到了一堆无法修复的错误。此外,我为标签设置简单属性的方式似乎有点冗长:是否有更简单的方法来获取属性并将其显示为标签?

这是我的工作示例:

const template = document.createElement('template');
template.innerHTML = `
<style>
:host {
display: block;
font-family: sans-serif;
text-align: center;
}

button {
border: none;
cursor: pointer;
}

ul {
list-style: none;
padding: 0;
}
</style>
<h1>To dos</h1>

<lable id="lable1"></lable>
<select></select>
`;

class TodoApp extends HTMLElement {
constructor() {
super();

this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
this.$todoList = this._shadowRoot.querySelector('select');
this.label1 = this._shadowRoot.getElementById('lable1')

}

static get observedAttributes() {
return ['att1'];
}

attributeChangedCallback(name, oldValue, newValue) {
this.label1.innerText = this.getAttribute('att1');
}

renderTodoList() {
this.$todoList.innerHTML = '';

this.todosArray.forEach((todoP) => {
let $todoItem = document.createElement('option');
$todoItem.text = todoP.text;
$todoItem.value = todoP.id;
this.$todoList.appendChild($todoItem);
});
}

set todos(value) {
this.todosArray = value;
this.renderTodoList();
}

}

window.customElements.define('to-do-app', TodoApp);

当我添加一个 connectedCallback() 方法并在那里创建影子 dom 时,我得到了一堆错误。我的标记只是:

<to-do-app att1="value 1 attribute"></to-do-app>

我试过这个:

class TodoApp extends HTMLElement {
constructor() {
super();
this.label1 = '';
}

connectedCallback() {
this._shadowRoot = this.attachShadow({ 'mode': 'open' });
this._shadowRoot.appendChild(template.content.cloneNode(true));
this.$todoList = this._shadowRoot.querySelector('select');
this.label1 = this._shadowRoot.getElementById('lable1')

}

static get observedAttributes() {
return ['att1'];
}

attributeChangedCallback(name, oldValue, newValue) {
this.label1.innerText = this.getAttribute('att1');
}

但是得到错误:

TypeError: can't assign to property "innerText" on "": not an object

最佳答案

我是 not sure at all it's best to define the Shadow DOM in connectedCallback() (除非您想使用 Shadow DOM polyfill。您是从哪里读到的?

无论如何,如果你的例子是connectedCallback() , 错误是由于 attributeChangedCallback()connectedCallback() 之前调用.

这就是为什么属性 this.label1 attributeChangeCallback() 时尚未设置被称为。

相反,测试属性是否存在:

attributeChangedCallback(name, oldValue, newValue) {
if ( this.label1 )
this.label1.innerText = this.getAttribute('att1');
}

并且,在渲染组件时,测试属性是否存在:

connectedCallback() {
//...
this.label1 = this._shadowRoot.getElementById('lable1')
if ( this.getAttribute( 'att1' ) )
this.label1.innerText = this.getAttribute( 'att1' )
}

更新

读取属性的最佳方式取决于您何时需要它。在您的用例中,因为当您需要它时它已经在标记中了 connectedCallback() ,您可以使用 this.getAttribute() 获取它.

分配它的值,也许你应该使用template literal使用变量而不是 <template>元素。

let label = this.getAttribute( 'att1' )
this.shadowRoot.innerHTML = `<label>${label}</label>`

关于javascript - 使用 connectedCallback() 会破坏 Web 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56889259/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com